Zero Data Wrap – Unified API for remoteStorage + Fission + other?

I started working on a JavaScript library that enables apps to support multiple 0data protocols with the same API, currently remoteStorage, Fission, and any object that conforms to a certain interface. Maybe SOLID someday?

I configured my sample Fission app to log in with a remoteStorage address:

http://fission-proof.5apps.com

Comparing APIs

I think the API simplifies the experience for my use cases, especially since I stopped using JSON schema a while ago in favour of writing objects directly (perhaps it could be integrated later).

Setup

const remoteStorage = new RemoteStorage({ modules: [{
	name: 'bravo',
	builder (privateClient, publicClient) {
	  return {
	    exports: {
	    	storeItem (path, object) {
	    		return privateClient.storeFile('application/json', path, JSON.stringify(object));
	    	},
	    },
	  };
	},
}] });

remoteStorage.access.claim('bravo', 'rw');

remoteStorage.caching.enable(`/bravo/`);

remoteStorage.on('ready', function () {
   // ready
});

==

const api = await zerodatawrap.ZDRWrap({
  ZDRParamLibrary: RemoteStorage,
  ZDRParamScopes: [{
    ZDRScopeKey: 'alfa',
    ZDRScopeDirectory: 'bravo',
  }],
});

// ready

Write an object

await remoteStorage.bravo.storeItem('/charlie.json', JSON.stringify({
  foo: 'bar',
}));

==

await api.alfa.ZDRStorageWriteObject('charlie.json', {
  foo: 'bar',
});

Get an array of objects

Object.entries(await remoteStorage.bravo.getAll('', false)).reduce(function (coll, [key, value]) {
	// ignore folders
	if (key.slice(-1) === '/') {
		return coll;
	}

	// ignore non-local
	if (value === true) {
		return coll;
	}

	return coll.concat(value);
}, []);

==

Object.values(await api.alfa.ZDRStorageListObjects());

Sync events

const remoteStorage = new RemoteStorage({ modules: [{
	name: 'bravo',
	builder (privateClient, publicClient) {
		privateClient.on('change', function (event) {
			// filter events based on model logic

			// …

			// determine if create/update/delete/conflict

			// …

			// respond with oldValue or newValue

			// …
		});
	  return {
	    exports: {
	    	storeItem (path, object) {
	    		return privateClient.storeFile('application/json', path, JSON.stringify(object));
	    	},
	    },
	  };
	},
}] });

// …

==

const api = zerodatawrap.ZDRWrap({

  // …

  ZDRParamScopes: [{

    // …

    // sync events are linked to model definitions
    ZDRScopeSchemas: [{

      // …

      ZDRSchemaDispatchSyncCreate (object) {
        // respond to remote create
      },
      ZDRSchemaDispatchSyncUpdate (object) {
        // respond to remote update
      },
      ZDRSchemaDispatchSyncDelete (object) {
        // respond to remote delete
      },
      ZDRSchemaDispatchSyncConflict (event) {
        // respond to remote conflict
      },

      // …

    }],

    // …

  }],

  // …

});

Anyway, it’s a work in progress that has missing elements (like public folders), but I hope it can make it easier for other people to integrate with remoteStorage. Any feedback or testing would be appreciated especially with storing files and buffers as I don’t use those much. I’ll share this more publicly once it’s more stable.

I made a corresponding post on the Fission forum in case anyone wants to get a sense of the other APIs.