@platform/cell.typesystem
Version:
The 'strongly typed sheets' system of the CellOS.
298 lines (297 loc) • 13 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TypedSheet = void 0;
var tslib_1 = require("tslib");
var rxjs_1 = require("rxjs");
var operators_1 = require("rxjs/operators");
var TypeSystem_core_1 = require("../../TypeSystem.core");
var common_1 = require("./common");
var TypedSheetData_1 = require("./TypedSheetData");
var TypedSheetState_1 = require("./TypedSheetState");
var TypedSheet_SheetPool_1 = require("../TypedSheet.SheetPool");
var TypeSystem_fetch_1 = require("../../TypeSystem.fetch");
var fromClient = function (client) {
var fetch = TypeSystem_fetch_1.fetcher.fromClient(client);
return {
load: function (ns) { return TypedSheet.load({ fetch: fetch, ns: ns }); },
};
};
var TypedSheet = (function () {
function TypedSheet(args) {
this._dispose$ = new rxjs_1.Subject();
this._data = {};
this.dispose$ = this._dispose$.pipe((0, operators_1.share)());
this.uri = common_1.Uri.ns(args.uri);
this.implements = common_1.Uri.ns(args.implements);
this.pool = args.pool;
var self = this;
var pool = this.pool;
var cache = args.cache || common_1.MemoryCache.create();
var event$ = args.event$ || new rxjs_1.Subject();
var dispose$ = this.dispose$;
this.event$ = event$.asObservable().pipe((0, operators_1.takeUntil)(dispose$), (0, operators_1.share)());
this.state = TypedSheetState_1.TypedSheetState.create({ sheet: self, event$: event$, fetch: args.fetch, cache: cache });
this._ctx = TypedSheet.ctx({ fetch: this.state.fetch, event$: event$, dispose$: dispose$, cache: cache, pool: pool });
this._typeDefs = args.types;
this._errorList = common_1.ErrorList.create({ defaultType: common_1.ERROR.TYPE.SHEET, errors: args.errors });
pool.add(self);
}
TypedSheet.ctx = function (args) {
var fetch = args.fetch;
var cache = args.cache || common_1.MemoryCache.create();
var event$ = args.event$ || new rxjs_1.Subject();
var dispose$ = args.dispose$ || new rxjs_1.Subject();
var pool = args.pool || TypedSheet_SheetPool_1.SheetPool.create();
return {
event$: event$,
dispose$: dispose$,
fetch: fetch,
cache: cache,
pool: pool,
sheet: {
load: function (args) {
return TypedSheet.load((0, tslib_1.__assign)((0, tslib_1.__assign)({}, args), { fetch: fetch, cache: cache, event$: event$ }));
},
create: function (args) {
return TypedSheet.create((0, tslib_1.__assign)((0, tslib_1.__assign)({}, args), { fetch: fetch, cache: cache, event$: event$ }));
},
},
};
};
TypedSheet.load = function (args) {
var _a, _b, _c, _d;
return (0, tslib_1.__awaiter)(this, void 0, void 0, function () {
var fetch, cache, event$, ns, sheetNs, pool, res, err, implementsNs, typeDefs, types, errors;
return (0, tslib_1.__generator)(this, function (_e) {
switch (_e.label) {
case 0:
fetch = args.fetch, cache = args.cache, event$ = args.event$;
ns = args.ns.toString();
if (ns.includes(':') && !common_1.Uri.is.type(['NS', 'CELL', 'COLUMN', 'ROW'], ns)) {
throw new Error("The uri (" + args.ns + ") cannot be resolved to a namespace.");
}
sheetNs = common_1.Uri.toNs(args.ns);
pool = args.pool || TypedSheet_SheetPool_1.SheetPool.create();
if (pool.exists(args.ns)) {
return [2, pool.sheet(args.ns)];
}
return [4, args.fetch.getNs({ ns: sheetNs.toString() })];
case 1:
res = _e.sent();
if (res.error) {
throw new Error(res.error.message);
}
if (!((_b = (_a = res.ns) === null || _a === void 0 ? void 0 : _a.type) === null || _b === void 0 ? void 0 : _b.implements)) {
err = "The namespace (" + sheetNs + ") does not contain an \"implements\" type reference.";
throw new Error(err);
}
implementsNs = common_1.Uri.ns((_d = (_c = res.ns) === null || _c === void 0 ? void 0 : _c.type) === null || _d === void 0 ? void 0 : _d.implements);
return [4, TypeSystem_core_1.TypeClient.load({
ns: implementsNs.toString(),
fetch: fetch,
cache: cache,
})];
case 2:
typeDefs = _e.sent();
types = typeDefs.defs;
errors = typeDefs.errors;
return [2, new TypedSheet({
uri: sheetNs,
implements: implementsNs,
types: types,
fetch: fetch,
cache: cache,
event$: event$,
errors: errors,
pool: pool,
})];
}
});
});
};
TypedSheet.create = function (args) {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function () {
var fetch, event$, cache, implementsNs, sheetNs, pool, typeDefs, types, errors;
return (0, tslib_1.__generator)(this, function (_a) {
switch (_a.label) {
case 0:
fetch = args.fetch, event$ = args.event$, cache = args.cache;
implementsNs = common_1.Uri.ns(args.implements);
sheetNs = args.ns ? common_1.Uri.ns(args.ns) : common_1.Uri.create.ns(common_1.Uri.cuid());
pool = args.pool || TypedSheet_SheetPool_1.SheetPool.create();
if (args.ns && pool.exists(args.ns)) {
return [2, pool.sheet(args.ns)];
}
return [4, TypeSystem_core_1.TypeClient.load({
ns: implementsNs.toString(),
fetch: fetch,
cache: cache,
})];
case 1:
typeDefs = _a.sent();
types = typeDefs.defs;
errors = typeDefs.errors;
return [2, new TypedSheet({
uri: sheetNs,
implements: implementsNs,
types: types,
fetch: fetch,
cache: cache,
event$: event$,
errors: errors,
pool: pool,
})];
}
});
});
};
TypedSheet.prototype.dispose = function () {
this._data = {};
this._dispose$.next();
this._dispose$.complete();
this.state.dispose();
};
Object.defineProperty(TypedSheet.prototype, "isDisposed", {
get: function () {
return this._dispose$.isStopped;
},
enumerable: false,
configurable: true
});
Object.defineProperty(TypedSheet.prototype, "ok", {
get: function () {
return this.errors.length === 0;
},
enumerable: false,
configurable: true
});
Object.defineProperty(TypedSheet.prototype, "errors", {
get: function () {
return this._errorList.list;
},
enumerable: false,
configurable: true
});
Object.defineProperty(TypedSheet.prototype, "changes", {
get: function () {
return this.state.changes;
},
enumerable: false,
configurable: true
});
Object.defineProperty(TypedSheet.prototype, "types", {
get: function () {
if (!this._types) {
var types_1 = [];
this._typeDefs.forEach(function (def) {
var typename = def.typename, columns = def.columns;
var item = types_1.find(function (item) { return item.typename === typename; });
if (item) {
item.columns = (0, tslib_1.__spreadArray)((0, tslib_1.__spreadArray)([], item.columns, true), columns, true);
}
else {
types_1.push({ typename: typename, columns: columns });
}
});
this._types = types_1;
}
return this._types;
},
enumerable: false,
configurable: true
});
TypedSheet.prototype.toString = function () {
return this.uri.toString();
};
TypedSheet.prototype.info = function () {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function () {
var res, exists, ns;
return (0, tslib_1.__generator)(this, function (_a) {
switch (_a.label) {
case 0:
this.throwIfDisposed('info');
return [4, this._ctx.fetch.getNs({ ns: this.uri.toString() })];
case 1:
res = _a.sent();
exists = Boolean(res.ns);
ns = (res.ns || {});
return [2, { exists: exists, ns: ns }];
}
});
});
};
TypedSheet.prototype.data = function (input) {
this.throwIfDisposed('data');
var args = (typeof input === 'string' ? { typename: input } : input);
var typename = args.typename;
var ctx = this._ctx;
if (this._data[typename]) {
var res_1 = this._data[typename];
if (args.range && res_1.range !== args.range) {
res_1.expandRange(args.range);
}
return res_1;
}
var defs = this._typeDefs;
var def = defs.find(function (def) { return def.typename === typename; });
if (!def) {
var names = defs.map(function (def) { return "'" + def.typename + "'"; }).join(', ');
var err = "Definitions for typename '" + typename + "' not found. Available typenames: " + names + ".";
throw new Error(err);
}
var self = this;
var types = def.columns;
var res = TypedSheetData_1.TypedSheetData.create({
sheet: self,
typename: typename,
types: types,
ctx: ctx,
range: args.range,
});
this._data[typename] = res;
return res;
};
TypedSheet.prototype.change = function (changes) {
var _this = this;
this.throwIfDisposed('change');
if (changes.ns) {
var change = changes.ns;
if (this.isThisNamespace(change.ns)) {
this.state.change.ns(change.to);
}
else {
var ns = this.uri.toString();
var err = "Requested change to [" + change.ns + "] is not in sheet [" + ns + "]";
throw new Error(err);
}
}
if (changes.cells) {
var cells_1 = changes.cells;
Object.keys(cells_1)
.map(function (key) { return ({ key: key, change: cells_1[key] }); })
.forEach(function (e) {
if (_this.isThisNamespace(e.change.ns)) {
_this.state.change.cell(e.key, e.change.to);
}
else {
var ns = _this.uri.toString();
var cell = common_1.Uri.create.cell(e.change.ns, e.change.key);
var err = "Requested change to [" + cell + "] is not in sheet [" + ns + "]";
throw new Error(err);
}
});
}
return this;
};
TypedSheet.prototype.throwIfDisposed = function (action) {
if (this.isDisposed) {
throw new Error("Cannot " + action + " because [TypedSheet] is disposed.");
}
};
TypedSheet.prototype.isThisNamespace = function (input) {
return common_1.Uri.strip.ns(input) === this.uri.id;
};
TypedSheet.client = fromClient;
return TypedSheet;
}());
exports.TypedSheet = TypedSheet;