@vuu-ui/vuu-data-test 3.3.17 → 4.0.0-alpha.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/README.md +8 -0
  2. package/package.json +10 -7
  3. package/src/Table.js +8 -5
  4. package/src/core/module/ModuleContainer.js +8 -0
  5. package/src/core/module/VuuModule.js +27 -3
  6. package/src/core/table/TableContainer.js +1 -1
  7. package/src/index.js +3 -0
  8. package/src/local-datasource-provider/LocalDatasourceProvider.js +8 -3
  9. package/src/module-admin/ModuleAdminModule.js +60 -0
  10. package/src/module-admin/index.js +3 -0
  11. package/src/module-admin/module-admin-schemas.js +99 -0
  12. package/src/module-admin/snapshot-projection.js +57 -0
  13. package/src/schemas.js +8 -2
  14. package/src/user-admin/UserAdminModule.js +412 -0
  15. package/src/user-admin/index.js +3 -0
  16. package/src/user-admin/initialSnapshot.js +477 -0
  17. package/src/user-admin/snapshot-projection.js +151 -0
  18. package/types/TickingArrayDataSource.d.ts +1 -1
  19. package/types/basket/BasketModule.d.ts +9 -9
  20. package/types/basket/reference-data/prices.d.ts +1 -1
  21. package/types/core/module/ModuleContainer.d.ts +6 -3
  22. package/types/core/module/VuuModule.d.ts +3 -0
  23. package/types/core/table/TableContainer.d.ts +5 -5
  24. package/types/index.d.ts +3 -0
  25. package/types/local-datasource-provider/LocalDatasourceProvider.d.ts +2 -2
  26. package/types/schemas.d.ts +5 -3
  27. package/types/simul/reference-data/instruments-extended.d.ts +1 -1
  28. package/types/simul/reference-data/instruments.d.ts +1 -1
  29. package/types/simul/reference-data/orders.d.ts +1 -1
  30. package/types/simul/reference-data/parent-child-orders.d.ts +2 -2
  31. package/types/simul/reference-data/prices.d.ts +1 -1
  32. package/types/vuu-row-generator.d.ts +1 -1
package/README.md CHANGED
@@ -0,0 +1,8 @@
1
+ # `@vuu-ui/vuu-data-test`
2
+
3
+ ## Admin test module dependencies
4
+
5
+ The `USER_ADMIN` and `MODULE_DISCOVERY` test modules use the published
6
+ `@heswell/user-admin` and `@heswell/module-admin` packages. Standard
7
+ `npm install` setup is sufficient. Browser code imports only the browser-safe
8
+ `contracts` subpath for module-admin.
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
- "version": "3.3.17",
2
+ "version": "4.0.0-alpha.10",
3
3
  "main": "./src/index.js",
4
+ "type": "module",
4
5
  "author": "heswell",
5
6
  "license": "Apache-2.0",
6
7
  "scripts": {
@@ -9,13 +10,16 @@
9
10
  "type-defs": "node ../../scripts/build-type-defs.mjs"
10
11
  },
11
12
  "dependencies": {
12
- "@vuu-ui/vuu-data-local": "3.3.17",
13
- "@vuu-ui/vuu-utils": "3.3.17"
13
+ "@heswell/module-admin": "1.0.0",
14
+ "@heswell/user-admin": "1.0.1",
15
+ "@vuu-ui/vuu-data-editing": "4.0.0-alpha.10",
16
+ "@vuu-ui/vuu-data-local": "4.0.0-alpha.10",
17
+ "@vuu-ui/vuu-utils": "4.0.0-alpha.10"
14
18
  },
15
19
  "devDependencies": {
16
- "@vuu-ui/vuu-protocol-types": "3.3.17",
17
- "@vuu-ui/vuu-data-types": "3.3.17",
18
- "@vuu-ui/vuu-table-types": "3.3.17"
20
+ "@vuu-ui/vuu-data-types": "4.0.0-alpha.10",
21
+ "@vuu-ui/vuu-protocol-types": "4.0.0-alpha.10",
22
+ "@vuu-ui/vuu-table-types": "4.0.0-alpha.10"
19
23
  },
20
24
  "sideEffects": false,
21
25
  "files": [
@@ -32,6 +36,5 @@
32
36
  },
33
37
  "module": "./src/index.js",
34
38
  "name": "@vuu-ui/vuu-data-test",
35
- "type": "module",
36
39
  "types": "types/index.d.ts"
37
40
  }
package/src/Table.js CHANGED
@@ -20,7 +20,7 @@ class Table extends EventEmitter {
20
20
  }
21
21
  buildIndex() {
22
22
  for(let i = 0; i < this.#data.length; i++){
23
- const key = this.#data[i][this.#indexOfKey];
23
+ const key = String(this.#data[i][this.#indexOfKey]);
24
24
  this.#index.set(key, i);
25
25
  }
26
26
  }
@@ -41,14 +41,17 @@ class Table extends EventEmitter {
41
41
  if (-1 !== index) {
42
42
  this.#index.delete(key);
43
43
  this.#data.splice(index, 1);
44
- for(let i = index; i < this.#data.length; i++)this.#index.set(this.#data[i][this.#indexOfKey], i);
44
+ for(let i = index; i < this.#data.length; i++)this.#index.set(String(this.#data[i][this.#indexOfKey]), i);
45
45
  if (emitEvent) this.emit("delete", key);
46
46
  } else throw Error(`[Table] delete key ${key} not found`);
47
47
  }
48
48
  insert(row, emitEvent = true) {
49
49
  const index = this.#data.length;
50
+ const createdTime = Date.now();
51
+ row[this.#dataMap.vuuUpdatedTimestamp] = createdTime;
52
+ row[this.#dataMap.vuuCreatedTimestamp] = createdTime;
50
53
  this.#data.push(row);
51
- const key = row[this.#indexOfKey];
54
+ const key = String(row[this.#indexOfKey]);
52
55
  this.#index.set(key, index);
53
56
  if (emitEvent) this.emit("insert", row);
54
57
  }
@@ -57,7 +60,7 @@ class Table extends EventEmitter {
57
60
  return this.#data[index];
58
61
  }
59
62
  update(key, columnName, value) {
60
- const rowIndex = this.#data.findIndex((row)=>row[this.#indexOfKey] === key);
63
+ const rowIndex = this.#data.findIndex((row)=>String(row[this.#indexOfKey]) === key);
61
64
  const colIndex = this.#dataMap[columnName];
62
65
  if (-1 !== rowIndex) {
63
66
  const row = this.#data[rowIndex];
@@ -74,7 +77,7 @@ class Table extends EventEmitter {
74
77
  }
75
78
  updateRow(row) {
76
79
  const key = row[this.#indexOfKey];
77
- const rowIndex = this.#data.findIndex((row)=>row[this.#indexOfKey] === key);
80
+ const rowIndex = this.#data.findIndex((row)=>String(row[this.#indexOfKey]) === String(key));
78
81
  if (-1 !== rowIndex) {
79
82
  const tsIndex = this.#dataMap.vuuUpdatedTimestamp;
80
83
  const lastUpdated = Date.now();
@@ -8,6 +8,9 @@ class ModuleContainer {
8
8
  register(module) {
9
9
  this.#modules.set(module.name, module);
10
10
  }
11
+ has(name) {
12
+ return this.#modules.has(name);
13
+ }
11
14
  get(name) {
12
15
  const module = this.#modules.get(name);
13
16
  if (module) return module;
@@ -18,4 +21,9 @@ class ModuleContainer {
18
21
  }
19
22
  }
20
23
  var module_ModuleContainer = ModuleContainer.instance;
24
+ const ensureVuuModule = (module)=>{
25
+ if (!ModuleContainer.instance.has(module.name)) ModuleContainer.instance.register(module);
26
+ return module;
27
+ };
21
28
  export default module_ModuleContainer;
29
+ export { ensureVuuModule };
@@ -22,6 +22,11 @@ class VuuModule {
22
22
  this.#sessionTableMessageColumn = sessionTableMessageColumn;
23
23
  ModuleContainer.register(this);
24
24
  }
25
+ get includeDefaultServices() {
26
+ return true;
27
+ }
28
+ async beforeSessionSave(_sourceTable, _sessionTable) {}
29
+ async afterSessionSave(_sourceTable, _sessionTable) {}
25
30
  getTableSchema(tableName) {
26
31
  return this.schemas[tableName] ?? this.#sessionTableMap[tableName]?.schema;
27
32
  }
@@ -155,8 +160,9 @@ class VuuModule {
155
160
  };
156
161
  getServices(tableName) {
157
162
  const tableServices = this.services?.[tableName];
158
- if (Array.isArray(tableServices)) return this.#moduleServices.concat(tableServices);
159
- return this.#moduleServices;
163
+ const defaultServices = this.includeDefaultServices ? this.#moduleServices : [];
164
+ if (Array.isArray(tableServices)) return defaultServices.concat(tableServices);
165
+ return defaultServices;
160
166
  }
161
167
  getMenuServices(tableName) {
162
168
  const tableServices = this.menuServices?.[tableName];
@@ -221,7 +227,9 @@ class VuuModule {
221
227
  }
222
228
  return {
223
229
  type: "SUCCESS_RESULT",
224
- data: void 0
230
+ data: {
231
+ deletedKeys: selectedRowIds
232
+ }
225
233
  };
226
234
  }
227
235
  return {
@@ -492,6 +500,14 @@ class VuuModule {
492
500
  data: void 0
493
501
  };
494
502
  {
503
+ try {
504
+ await this.beforeSessionSave(sourceTable, sessionTable);
505
+ } catch (error) {
506
+ return {
507
+ errorMessage: error instanceof Error ? error.message : "Unable to prepare session changes",
508
+ type: "ERROR_RESULT"
509
+ };
510
+ }
495
511
  let rejectedCount = 0;
496
512
  const vuuMsgIdx = sessionTable.map[this.#sessionTableMessageColumn];
497
513
  const actionIdx = sessionTable.map.vuuAction;
@@ -526,6 +542,14 @@ class VuuModule {
526
542
  errorMessage: "stale update",
527
543
  type: "ERROR_RESULT"
528
544
  };
545
+ try {
546
+ await this.afterSessionSave(sourceTable, sessionTable);
547
+ } catch (error) {
548
+ return {
549
+ errorMessage: error instanceof Error ? error.message : "Unable to finalize session changes",
550
+ type: "ERROR_RESULT"
551
+ };
552
+ }
529
553
  return {
530
554
  type: "SUCCESS_RESULT",
531
555
  data: void 0
@@ -10,7 +10,7 @@ class TableContainer {
10
10
  return TableContainer.#instance;
11
11
  }
12
12
  #tables = new Map();
13
- createTable = (schema, data, dataMap, updateGenerator)=>{
13
+ createTable = (schema, data = [], dataMap = buildDataColumnMapFromSchema(schema), updateGenerator)=>{
14
14
  const table = new Table(schema, data, dataMap, updateGenerator);
15
15
  this.addTable(table);
16
16
  return table;
package/src/index.js CHANGED
@@ -5,8 +5,11 @@ export * from "./makeSuggestions.js";
5
5
  export * from "./schemas.js";
6
6
  export * from "./simul/index.js";
7
7
  export * from "./basket/index.js";
8
+ export * from "./module-admin/index.js";
9
+ export * from "./user-admin/index.js";
8
10
  export * from "./test/index.js";
9
11
  export * from "./TickingArrayDataSource.js";
10
12
  export * from "./vuu-row-generator.js";
13
+ export { ensureVuuModule } from "./core/module/ModuleContainer.js";
11
14
  export { default as tableContainer } from "./core/table/TableContainer.js";
12
15
  export { Table, buildDataColumnMap, buildDataColumnMapFromSchema } from "./Table.js";
@@ -1,5 +1,6 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
- import { DataProvider } from "@vuu-ui/vuu-utils";
2
+ import { DataProvider } from "@vuu-ui/core";
3
+ import { DataProvider as vuu_utils_DataProvider } from "@vuu-ui/vuu-utils";
3
4
  import ModuleContainer from "../core/module/ModuleContainer.js";
4
5
  import TableContainer from "../core/table/TableContainer.js";
5
6
  const serverAPI = {
@@ -37,9 +38,13 @@ class VuuDataSource {
37
38
  return module.createDataSource(table.table, viewport, config);
38
39
  }
39
40
  }
40
- const LocalDataSourceProvider = ({ children })=>/*#__PURE__*/ jsx(DataProvider, {
41
+ const LocalDataSourceProvider = ({ children })=>/*#__PURE__*/ jsx(vuu_utils_DataProvider, {
41
42
  VuuDataSource: VuuDataSource,
42
43
  getServerAPI: getServerAPI,
43
- children: children
44
+ children: /*#__PURE__*/ jsx(DataProvider, {
45
+ VuuDataSource: VuuDataSource,
46
+ getServerAPI: getServerAPI,
47
+ children: children
48
+ })
44
49
  });
45
50
  export { LocalDataSourceProvider };
@@ -0,0 +1,60 @@
1
+ import { DEFAULT_MODULE_DEFINITIONS } from "@heswell/module-admin/contracts";
2
+ import { VuuModule } from "../core/module/VuuModule.js";
3
+ import TableContainer from "../core/table/TableContainer.js";
4
+ import { buildDataColumnMapFromSchema } from "../Table.js";
5
+ import { MODULE_ADMIN_MODULE_NAME, MODULE_ADMIN_TABLE_SCHEMAS } from "./module-admin-schemas.js";
6
+ import { reconcileModuleAdminTables } from "./snapshot-projection.js";
7
+ const createTable = (tableName)=>{
8
+ const schema = MODULE_ADMIN_TABLE_SCHEMAS[tableName];
9
+ return TableContainer.createTable(schema, [], buildDataColumnMapFromSchema(schema));
10
+ };
11
+ const createTables = ()=>({
12
+ modulePermissions: createTable("modulePermissions"),
13
+ modules: createTable("modules")
14
+ });
15
+ const MODULE_ADMIN_INITIAL_SNAPSHOT = {
16
+ moduleAccessRoles: [
17
+ {
18
+ moduleName: "moduleAdmin",
19
+ role: "module-admin-access"
20
+ },
21
+ {
22
+ moduleName: "userAdmin",
23
+ role: "user-admin-access"
24
+ },
25
+ {
26
+ moduleName: "basket-trading",
27
+ role: "basket-trading-access"
28
+ }
29
+ ],
30
+ modules: DEFAULT_MODULE_DEFINITIONS,
31
+ timestamp: 1710000000000
32
+ };
33
+ class ModuleAdminModule extends VuuModule {
34
+ #tables;
35
+ constructor(snapshot = MODULE_ADMIN_INITIAL_SNAPSHOT){
36
+ super(MODULE_ADMIN_MODULE_NAME);
37
+ this.#tables = createTables();
38
+ reconcileModuleAdminTables(snapshot, this.#tables);
39
+ }
40
+ get menus() {
41
+ return {
42
+ modulePermissions: void 0,
43
+ modules: void 0
44
+ };
45
+ }
46
+ get includeDefaultServices() {
47
+ return false;
48
+ }
49
+ get menuServices() {}
50
+ get schemas() {
51
+ return MODULE_ADMIN_TABLE_SCHEMAS;
52
+ }
53
+ get services() {}
54
+ get tables() {
55
+ return this.#tables;
56
+ }
57
+ get visualLinks() {}
58
+ }
59
+ const moduleAdminModule = new ModuleAdminModule();
60
+ export { MODULE_ADMIN_INITIAL_SNAPSHOT, ModuleAdminModule, moduleAdminModule };
@@ -0,0 +1,3 @@
1
+ export { MODULE_ADMIN_INITIAL_SNAPSHOT, ModuleAdminModule, moduleAdminModule } from "./ModuleAdminModule.js";
2
+ export { MODULE_ADMIN_MODULE_NAME, MODULE_ADMIN_TABLE_SCHEMAS } from "./module-admin-schemas.js";
3
+ export { projectModuleAdminSnapshot, reconcileModuleAdminTables } from "./snapshot-projection.js";
@@ -0,0 +1,99 @@
1
+ import { VUU_DEFAULT_COLUMNS } from "../default-column-definitions.js";
2
+ const DEFAULT_RANGE_LIMITS = {
3
+ maxRangeEnd: 1000000,
4
+ maxRangeWidth: 1000
5
+ };
6
+ const MODULE_ADMIN_MODULE_NAME = "MODULE_DISCOVERY";
7
+ const MODULE_ADMIN_TABLE_SCHEMAS = {
8
+ modules: {
9
+ columns: [
10
+ {
11
+ name: "id",
12
+ serverDataType: "int"
13
+ },
14
+ {
15
+ name: "name",
16
+ serverDataType: "string"
17
+ },
18
+ {
19
+ name: "title",
20
+ serverDataType: "string"
21
+ },
22
+ {
23
+ name: "description",
24
+ serverDataType: "string"
25
+ },
26
+ {
27
+ name: "version",
28
+ serverDataType: "int"
29
+ },
30
+ {
31
+ name: "enabled",
32
+ serverDataType: "boolean"
33
+ },
34
+ {
35
+ name: "location",
36
+ serverDataType: "string"
37
+ },
38
+ {
39
+ name: "path",
40
+ serverDataType: "string"
41
+ },
42
+ {
43
+ name: "mfComponent",
44
+ serverDataType: "string"
45
+ },
46
+ {
47
+ name: "mfScope",
48
+ serverDataType: "string"
49
+ },
50
+ {
51
+ name: "mfUrl",
52
+ serverDataType: "string"
53
+ },
54
+ {
55
+ name: "vuuConnectionId",
56
+ serverDataType: "string"
57
+ },
58
+ {
59
+ name: "vuuWebsocketUrl",
60
+ serverDataType: "string"
61
+ },
62
+ {
63
+ name: "vuuRestUrl",
64
+ serverDataType: "string"
65
+ },
66
+ ...VUU_DEFAULT_COLUMNS
67
+ ],
68
+ key: "id",
69
+ rangeLimits: DEFAULT_RANGE_LIMITS,
70
+ table: {
71
+ module: MODULE_ADMIN_MODULE_NAME,
72
+ table: "modules"
73
+ }
74
+ },
75
+ modulePermissions: {
76
+ columns: [
77
+ {
78
+ name: "id",
79
+ serverDataType: "int"
80
+ },
81
+ {
82
+ name: "module_id",
83
+ serverDataType: "int"
84
+ },
85
+ {
86
+ name: "role",
87
+ serverDataType: "string"
88
+ },
89
+ ...VUU_DEFAULT_COLUMNS
90
+ ],
91
+ key: "id",
92
+ rangeLimits: DEFAULT_RANGE_LIMITS,
93
+ table: {
94
+ module: MODULE_ADMIN_MODULE_NAME,
95
+ table: "modulePermissions"
96
+ }
97
+ }
98
+ };
99
+ export { MODULE_ADMIN_MODULE_NAME, MODULE_ADMIN_TABLE_SCHEMAS };
@@ -0,0 +1,57 @@
1
+ import { moduleDefinitionsToRows, modulePermissionsFor } from "@heswell/module-admin/contracts";
2
+ const rowsEqual = (left, right)=>left.length === right.length && left.every((value, index)=>value === right[index]);
3
+ const systemValues = (timestamp)=>({
4
+ vuuCreatedTimestamp: timestamp,
5
+ vuuMsg: "",
6
+ vuuUpdatedTimestamp: timestamp
7
+ });
8
+ const toRow = (table, values)=>table.schema.columns.map(({ name })=>values[name] ?? "");
9
+ const moduleValues = ([id, name, title, description, version, enabled, location, path, mfComponent, mfScope, mfUrl, vuuConnectionId, vuuWebsocketUrl, vuuRestUrl], timestamp)=>({
10
+ ...systemValues(timestamp),
11
+ description,
12
+ enabled,
13
+ id,
14
+ location,
15
+ mfComponent,
16
+ mfScope,
17
+ mfUrl,
18
+ name,
19
+ path,
20
+ title,
21
+ version,
22
+ vuuConnectionId,
23
+ vuuRestUrl,
24
+ vuuWebsocketUrl
25
+ });
26
+ const permissionValues = ([id, moduleId, role], timestamp)=>({
27
+ ...systemValues(timestamp),
28
+ id,
29
+ module_id: moduleId,
30
+ role
31
+ });
32
+ const projectModuleAdminSnapshot = (snapshot, tables)=>({
33
+ modulePermissions: modulePermissionsFor(snapshot.modules, snapshot.moduleAccessRoles).map((row)=>toRow(tables.modulePermissions, permissionValues(row, snapshot.timestamp))),
34
+ modules: moduleDefinitionsToRows(snapshot.modules).map((row)=>toRow(tables.modules, moduleValues(row, snapshot.timestamp)))
35
+ });
36
+ const reconcileModuleAdminTables = (snapshot, tables)=>{
37
+ const projected = projectModuleAdminSnapshot(snapshot, tables);
38
+ for (const tableName of Object.keys(tables)){
39
+ const table = tables[tableName];
40
+ const desiredRows = projected[tableName];
41
+ const keyIndex = table.map[table.schema.key];
42
+ const desiredKeys = new Set(desiredRows.map((row)=>String(row[keyIndex])));
43
+ for (const existingRow of [
44
+ ...table.data
45
+ ]){
46
+ const key = String(existingRow[keyIndex]);
47
+ if (!desiredKeys.has(key)) table.delete(key);
48
+ }
49
+ for (const row of desiredRows){
50
+ const key = String(row[keyIndex]);
51
+ const existingRow = table.findByKey(key);
52
+ if (void 0 === existingRow) table.insert(row);
53
+ else if (!rowsEqual(existingRow, row)) table.updateRow(row);
54
+ }
55
+ }
56
+ };
57
+ export { projectModuleAdminSnapshot, reconcileModuleAdminTables };
package/src/schemas.js CHANGED
@@ -1,15 +1,21 @@
1
1
  import { schemas } from "./basket/basket-schemas.js";
2
2
  import { schemas as simul_schemas_js_schemas } from "./simul/simul-schemas.js";
3
3
  import { testModule } from "./test/TestModule.js";
4
+ import { USER_ADMIN_TABLE_SCHEMAS } from "@heswell/user-admin/contracts";
5
+ import { MODULE_ADMIN_TABLE_SCHEMAS } from "./module-admin/index.js";
4
6
  const schemas_schemas = {
5
7
  ...schemas,
6
8
  ...simul_schemas_js_schemas,
7
- ...testModule.schemas
9
+ ...testModule.schemas,
10
+ ...USER_ADMIN_TABLE_SCHEMAS,
11
+ ...MODULE_ADMIN_TABLE_SCHEMAS
8
12
  };
9
13
  const allSchemas = {
10
14
  ...schemas,
11
15
  ...simul_schemas_js_schemas,
12
- ...testModule.schemas
16
+ ...testModule.schemas,
17
+ ...USER_ADMIN_TABLE_SCHEMAS,
18
+ ...MODULE_ADMIN_TABLE_SCHEMAS
13
19
  };
14
20
  const getAllSchemas = ()=>schemas_schemas;
15
21
  const getSchema = (tableName)=>{