UNPKG

@platform/cell.typesystem

Version:

The 'strongly typed sheets' system of the CellOS.

302 lines (301 loc) 14 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var operators_1 = require("rxjs/operators"); var TypeSystem_core_1 = require("../../TypeSystem.core"); var common_1 = require("./common"); var TypedSheetRef_1 = require("./TypedSheetRef"); var TypedSheetRefs_1 = require("./TypedSheetRefs"); var TypedSheetRow = (function () { function TypedSheetRow(args) { var _this = this; this._columns = []; this._prop = {}; this._refs = {}; this._data = {}; this._isLoaded = false; this._status = 'INIT'; this._loading = {}; this.typename = args.typename; this.uri = common_1.Uri.row(args.uri); this.index = Number.parseInt(this.uri.key, 10) - 1; this._columns = args.columns; this._ctx = args.ctx; this._sheet = args.sheet; var cellChange$ = this._ctx.event$.pipe(operators_1.filter(function (e) { return e.type === 'SHEET/change'; }), operators_1.map(function (e) { return e.payload; }), operators_1.filter(function (e) { return e.kind === 'CELL'; }), operators_1.map(function (_a) { var to = _a.to, ns = _a.ns, key = _a.key; return ({ to: to, uri: common_1.Uri.parse(common_1.Uri.create.cell(ns, key)) }); }), operators_1.filter(function (_a) { var uri = _a.uri; return uri.ok && uri.type === 'CELL' && uri.parts.ns === _this.uri.ns; }), operators_1.map(function (e) { return (tslib_1.__assign(tslib_1.__assign({}, e), { uri: e.uri.parts })); })); cellChange$ .pipe(operators_1.map(function (e) { var columnKey = common_1.Schema.coord.cell.toColumnKey(e.uri.key); var columnDef = _this._columns.find(function (def) { return def.column === columnKey; }); return tslib_1.__assign(tslib_1.__assign({}, e), { columnDef: columnDef }); }), operators_1.filter(function (e) { return Boolean(e.columnDef); }), operators_1.map(function (e) { return (tslib_1.__assign(tslib_1.__assign({}, e), { target: TypeSystem_core_1.TypeTarget.parse(e.columnDef.target) })); }), operators_1.filter(function (e) { return e.target.isValid && e.target.isInline; })) .subscribe(function (e) { _this.setData(e.columnDef, e.to); }); } Object.defineProperty(TypedSheetRow.prototype, "status", { get: function () { return this._status; }, enumerable: true, configurable: true }); Object.defineProperty(TypedSheetRow.prototype, "isLoaded", { get: function () { return this._isLoaded; }, enumerable: true, configurable: true }); Object.defineProperty(TypedSheetRow.prototype, "types", { get: function () { if (!this._types) { var map_1; var list_1; var columns_1 = this._columns; var row_1 = this.uri; var types_1 = (this._types = { get list() { if (!list_1) { list_1 = columns_1.map(function (type) { var uri; return tslib_1.__assign(tslib_1.__assign({}, type), { get uri() { return (uri || (uri = common_1.Uri.cell(common_1.Uri.create.cell(row_1.ns, "" + type.column + row_1.key)))); } }); }); } return list_1; }, get map() { if (!map_1) { map_1 = types_1.list.reduce(function (acc, type) { acc[type.prop] = type; return acc; }, {}); } return map_1; }, }); } return this._types; }, enumerable: true, configurable: true }); Object.defineProperty(TypedSheetRow.prototype, "props", { get: function () { var _this = this; if (!this._props) { var props_1 = {}; this._columns.forEach(function (typeDef) { var name = typeDef.prop; Object.defineProperty(props_1, name, { get: function () { return _this.prop(name).get(); }, set: function (value) { return _this.prop(name).set(value); }, }); }); this._props = props_1; } return this._props; }, enumerable: true, configurable: true }); TypedSheetRow.prototype.toString = function () { return this.uri.toString(); }; TypedSheetRow.prototype.load = function (options) { if (options === void 0) { options = {}; } return tslib_1.__awaiter(this, void 0, void 0, function () { var props, cacheKey, promise; var _this = this; return tslib_1.__generator(this, function (_a) { if (this.isLoaded && !options.force) { return [2, this]; } props = options.props; cacheKey = props ? "load:" + props.join(',') : 'load'; if (!options.force && this._loading[cacheKey]) { return [2, this._loading[cacheKey]]; } promise = new Promise(function (resolve, reject) { return tslib_1.__awaiter(_this, void 0, void 0, function () { var ns, index, sheet, query; var _this = this; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: this._status = 'LOADING'; ns = this.uri.ns; index = this.index; sheet = this._sheet; this.fire({ type: 'SHEET/row/loading', payload: { sheet: sheet, index: index } }); query = this.uri.key + ":" + this.uri.key; return [4, Promise.all(this._columns .filter(function (columnDef) { return (!props ? true : props.includes(columnDef.prop)); }) .map(function (columnDef) { return tslib_1.__awaiter(_this, void 0, void 0, function () { var res, key; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: return [4, this._ctx.fetch.getCells({ ns: ns, query: query })]; case 1: res = _a.sent(); key = "" + columnDef.column + (this.index + 1); this.setData(columnDef, (res.cells || {})[key] || {}); return [2]; } }); }); }))]; case 1: _a.sent(); this._status = 'LOADED'; this._isLoaded = true; this.fire({ type: 'SHEET/row/loaded', payload: { sheet: sheet, index: index } }); delete this._loading[cacheKey]; resolve(this); return [2]; } }); }); }); this._loading[cacheKey] = promise; return [2, promise]; }); }); }; TypedSheetRow.prototype.toObject = function () { var _this = this; return this._columns.reduce(function (acc, typeDef) { var prop = typeDef.prop; acc[prop] = _this.prop(prop).get(); return acc; }, {}); }; TypedSheetRow.prototype.type = function (prop) { var typeDef = this.findColumnByProp(prop); if (!typeDef) { var err = "The property '" + prop + "' is not defined by a column on [" + this.uri + "]"; throw new Error(err); } return typeDef; }; TypedSheetRow.prototype.prop = function (name) { var propname = name; if (this._prop[propname]) { return this._prop[propname]; } var self = this; var columnDef = this.findColumnByProp(name); var target = TypeSystem_core_1.TypeTarget.parse(columnDef.target); var typename = columnDef.type.typename; if (!target.isValid) { var err = "Property '" + name + "' (column " + columnDef.column + ") has an invalid target '" + columnDef.target + "'."; throw new Error(err); } var api = { get: function () { var done = function (result) { if (result === undefined && TypeSystem_core_1.TypeDefault.isTypeDefaultValue(columnDef.default)) { result = columnDef.default.value; } if (result === undefined && columnDef.type.isArray) { result = []; } return result; }; if (!target.isValid) { var err = "Cannot read property '" + columnDef.prop + "' (column " + columnDef.column + ") because the target '" + columnDef.target + "' is invalid."; throw new Error(err); } var cell = self._data[columnDef.column] || {}; if (target.isInline) { return done(TypeSystem_core_1.TypeTarget.inline(columnDef).read(cell)); } if (target.isRef) { if (self._refs[propname]) { return done(self._refs[propname]); } var links = cell.links; var typeDef = columnDef; var res = self.getOrCreateRef({ typename: typename, typeDef: typeDef, links: links }); self._refs[propname] = res.ref; return done(res.ref); } throw new Error("Failed to read property '" + name + "' (column " + columnDef.column + ")."); }, set: function (value) { if (target.isInline) { var isChanged = !common_1.R.equals(api.get(), value); if (isChanged) { var cell = self._data[columnDef.column] || {}; var data = TypeSystem_core_1.TypeTarget.inline(columnDef).write({ cell: cell, data: value }); self.fireChange(columnDef, data); } } if (target.isRef) { var err = "Cannot write to property '" + name + "' (column " + columnDef.column + ") because it is a REF target."; throw new Error(err); } return self; }, clear: function () { if (target.isInline) { api.set(undefined); } return self; }, }; this._prop[name] = api; return api; }; TypedSheetRow.prototype.fire = function (e) { this._ctx.event$.next(e); }; TypedSheetRow.prototype.findColumnByProp = function (prop) { var res = this._columns.find(function (def) { return def.prop === prop; }); if (!res) { var err = "Column-definition for the property '" + prop + "' not found."; throw new Error(err); } return res; }; TypedSheetRow.prototype.fireChange = function (columnDef, to) { var key = "" + columnDef.column + (this.index + 1); var ns = common_1.Uri.create.ns(this.uri.ns); this._ctx.event$.next({ type: 'SHEET/change', payload: { kind: 'CELL', ns: ns, key: key, to: to }, }); }; TypedSheetRow.prototype.setData = function (columnDef, data) { this._data[columnDef.column] = data; }; TypedSheetRow.prototype.getOrCreateRef = function (args) { var typename = args.typename, typeDef = args.typeDef, _a = args.links, links = _a === void 0 ? {} : _a; var ctx = this._ctx; var isArray = typeDef.type.isArray; var link = TypedSheetRefs_1.TypedSheetRefs.refLink({ typeDef: typeDef, links: links }).link; var exists = Boolean(link); var uri = common_1.Uri.create.cell(this.uri.ns, "" + typeDef.column + (this.index + 1)); var parent = { cell: common_1.Uri.cell(uri), sheet: this._sheet, }; var ref = isArray ? TypedSheetRefs_1.TypedSheetRefs.create({ typename: typename, typeDef: typeDef, ctx: ctx, parent: parent }) : TypedSheetRef_1.TypedSheetRef.create({ typename: typename, typeDef: typeDef, ctx: ctx }); return { ref: ref, exists: exists }; }; TypedSheetRow.create = function (args) { return new TypedSheetRow(args); }; TypedSheetRow.load = function (args) { return TypedSheetRow.create(args).load(); }; return TypedSheetRow; }()); exports.TypedSheetRow = TypedSheetRow;