Hacky support for adding notifications in Chrome

Since notifications are called synchronously after a write, we fake it by calling them manually for now. The future plan will be more involved, so some of that is stubbed out.
This commit is contained in:
Scott Kyle 2015-10-14 18:00:21 -07:00
parent b985e1f0a6
commit 78ec67cd6c
4 changed files with 67 additions and 4 deletions

19
lib/notifications.js Normal file
View File

@ -0,0 +1,19 @@
'use strict';
let util = require('./util');
let idKey = util.idKey;
let realmKey = util.realmKey;
exports.create = create;
function create(realmId, info) {
let notification = new Notification();
notification[realmKey] = realmId;
notification[idKey] = info.id;
return notification;
}
class Notification {}

View File

@ -2,24 +2,28 @@
let lists = require('./lists');
let objects = require('./objects');
let notifications = require('./notifications');
let results = require('./results');
let rpc = require('./rpc');
let types = require('./types');
let util = require('./util');
let realmKey = util.realmKey;
let notificationsKey = Symbol();
let notificationCallbackKey = Symbol();
// TODO: DATA
rpc.registerTypeConverter(types.DATE, (_, info) => new Date(info.value));
rpc.registerTypeConverter(types.LIST, lists.create);
rpc.registerTypeConverter(types.OBJECT, objects.create);
rpc.registerTypeConverter('ObjectTypesNOTIFICATION', notifications.create);
rpc.registerTypeConverter('ObjectTypesRESULTS', results.create);
class Realm {
constructor(config) {
let schema = typeof config == 'object' && config.schema;
let constructors = {};
for (let i = 0, len = schema ? schema.length : 0; i < len; i++) {
let item = schema[i];
let proto = item.prototype;
@ -29,14 +33,28 @@ class Realm {
constructors[proto.schema.name] = item;
}
}
let realmId = this[realmKey] = rpc.createRealm(Array.from(arguments));
objects.registerConstructors(realmId, constructors);
this[notificationsKey] = [];
}
addNotification(callback) {
// TODO
let realmId = this[realmKey];
if (!realmId) {
throw new TypeError('addNotification method was not called on a Realm object!');
}
if (typeof callback != 'function') {
throw new Error('Realm.addNotification must be passed function!');
}
let notification = rpc.callRealmMethod(realmId, 'addNotification', [callback]);
notification[notificationCallbackKey] = callback;
this[notificationsKey].push(notification);
}
write(callback) {
@ -59,6 +77,11 @@ class Realm {
}
rpc.commitTransaction(realmId);
for (let notification of this[notificationsKey]) {
let callback = notification[notificationCallbackKey];
callback(this, 'DidChangeNotification');
}
}
}

View File

@ -118,6 +118,10 @@ function clearTestState() {
}
function serialize(realmId, value) {
if (typeof value == 'function') {
return {type: 'ObjectTypesFUNCTION'};
}
if (!value || typeof value != 'object') {
return {value: value};
}

View File

@ -317,6 +317,13 @@ using RPCRequest = std::function<NSDictionary *(NSDictionary *dictionary)>;
@"schema": [self objectSchemaToJSONObject:results->object_schema]
};
}
else if (JSValueIsObjectOfClass(_context, value, RJSNotificationClass())) {
RPCObjectID oid = [self storeObject:jsObject];
return @{
@"type": @"ObjectTypesNOTIFICATION",
@"id": @(oid),
};
}
else if (RJSIsValueArray(_context, value)) {
size_t length = RJSValidatedListLength(_context, jsObject);
NSMutableArray *array = [NSMutableArray new];
@ -354,6 +361,16 @@ using RPCRequest = std::function<NSDictionary *(NSDictionary *dictionary)>;
return _objects[oid];
}
NSString *type = dict[@"type"];
if ([type isEqualToString:@"ObjectTypesFUNCTION"]) {
// FIXME: Make this actually call the function by its id once we need it to.
JSStringRef jsBody = JSStringCreateWithUTF8CString("");
JSObjectRef jsFunction = JSObjectMakeFunction(_context, NULL, 0, NULL, jsBody, NULL, 1, NULL);
JSStringRelease(jsBody);
return jsFunction;
}
id value = dict[@"value"];
if (!value) {
return JSValueMakeUndefined(_context);