@heswell/vuu-data-engine-local 2.1.0 → 3.0.0
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.
- package/README.md +159 -25
- package/index.js +3771 -3318
- package/legacy.js +8 -0
- package/package.json +8 -2
- package/src/EngineDataSource.d.ts +13 -3
- package/src/ModuleDataSource.d.ts +3 -3
- package/src/UpdateGenerator.d.ts +12 -0
- package/src/basket/BasketModule.d.ts +12 -2
- package/src/basket/index.d.ts +1 -1
- package/src/core/engine/LocalEngine.d.ts +62 -0
- package/src/core/filter/PermissionFilter.d.ts +2 -2
- package/src/core/module/VuuModule.d.ts +68 -1
- package/src/core/module/edit-hooks.d.ts +135 -0
- package/src/core/table/TableContainer.d.ts +35 -11
- package/src/core/table/defaultTableContainer.d.ts +6 -0
- package/src/data-utils.d.ts +7 -0
- package/src/demo-modules.d.ts +18 -0
- package/src/index.d.ts +7 -2
- package/src/legacy.d.ts +11 -0
- package/src/local-datasource-provider/LocalDatasourceProvider.d.ts +18 -7
- package/src/local-datasource-provider/createDataSourceProvider.d.ts +12 -0
- package/src/module-admin/ModuleAdminModule.d.ts +0 -1
- package/src/module-admin/index.d.ts +1 -1
- package/src/notifications/NotificationModule.d.ts +1 -0
- package/src/notifications/index.d.ts +0 -1
- package/src/simul/SimulModule.d.ts +9 -1
- package/src/simul/index.d.ts +1 -1
- package/src/simul/reference-data/instrument-prices.d.ts +2 -2
- package/src/simul/reference-data/instruments-extended.d.ts +1 -1
- package/src/simul/reference-data/instruments.d.ts +2 -3
- package/src/simul/reference-data/orders.d.ts +2 -3
- package/src/simul/reference-data/parent-child-orders.d.ts +15 -4
- package/src/simul/reference-data/prices.d.ts +18 -6
- package/src/test/TestModule.d.ts +2 -3
- package/src/user-admin/UserAdminModule.d.ts +0 -1
- package/src/user-admin/index.d.ts +1 -1
- package/src/basket/reference-data/prices.d.ts +0 -24
- package/src/core/module/ModuleContainer.d.ts +0 -15
- package/src/notifications/simulated/notificationsModule.d.ts +0 -5
package/legacy.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { getDefaultEngine, UserAdminModule, SimulatedNotificationsModule, registerDemoModules, ModuleAdminModule } from "./index.js";
|
|
2
|
+
const engine = getDefaultEngine();
|
|
3
|
+
const { simulModule: simulModule, basketModule: basketModule, testModule: testModule } = registerDemoModules(engine);
|
|
4
|
+
const moduleAdminModule = engine.register(new ModuleAdminModule());
|
|
5
|
+
const userAdminModule = engine.register(new UserAdminModule());
|
|
6
|
+
const notificationsModule = engine.register(SimulatedNotificationsModule());
|
|
7
|
+
export { AllowAllPermissionFilter, ArrayProxy, BaseUpdateGenerator, BasketModule, DUPLICATE_KEY, DefaultColumnGenerator, DefaultRowGenerator, DenyAllPermissionFilter, DismissNotificationRpcHandler, EngineDataSource, LocalDataSourceProvider, LocalEngine, MODULE_ADMIN_INITIAL_SNAPSHOT, MODULE_ADMIN_MODULE_NAME, MODULE_ADMIN_TABLE_SCHEMAS, ModuleAdminModule, ModuleDataSource, NotificationModule, NotificationsSchema, PermissionFilter, SAVE_FAILED, SAVE_NOT_PERMITTED, STALE_UPDATE, SimulModule, SimulatedNotificationsModule, SimulatedNotificationsProvider, Table, TableContainer, TestModule, TickingArrayDataSource, USER_ADMIN_INITIAL_SNAPSHOT, UserAdminModule, VUU_SYSTEM_COLUMNS, VuuModule, basketSchemas, buildDataColumnMap, buildDataColumnMapFromSchema, createDataSourceProvider, createJoinTable, createLocalEngine, createLocalVuuServer, createTable, defaultApplySessionSave, defaultCanEditSource, defaultGenerators, defaultGetStaleColumns, defaultIsEditableColumn, ensureVuuModule, formatMessage, getAllSchemas, getColumnAndRowGenerator, getCurrentUser, getDefaultEngine, getSchema, isBasketTable, isSimulTable, isSystemColumn, makeSuggestions, populateArray, projectModuleAdminSnapshot, projectUserAdminSnapshot, reconcileModuleAdminTables, reconcileUserAdminTables, registerDemoModules, resetDefaultEngine, schemas, setCurrentUser, simulSchemas, tableContainer, testSchemas, toColumn, toRange } from "./index.js";
|
|
8
|
+
export { basketModule, moduleAdminModule, notificationsModule, simulModule, testModule, userAdminModule };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@heswell/vuu-data-engine-local",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "In-browser Vuu server (VuuModule, tables, EngineDataSource) built on @heswell/vuu-table and @heswell/vuu-viewport",
|
|
5
5
|
"main": "./index.js",
|
|
6
6
|
"module": "./index.js",
|
|
@@ -9,6 +9,10 @@
|
|
|
9
9
|
".": {
|
|
10
10
|
"types": "./src/index.d.ts",
|
|
11
11
|
"import": "./index.js"
|
|
12
|
+
},
|
|
13
|
+
"./legacy": {
|
|
14
|
+
"types": "./src/legacy.d.ts",
|
|
15
|
+
"import": "./legacy.js"
|
|
12
16
|
}
|
|
13
17
|
},
|
|
14
18
|
"type": "module",
|
|
@@ -33,5 +37,7 @@
|
|
|
33
37
|
"@vuu-ui/vuu-utils": "^4.0.0-alpha.20",
|
|
34
38
|
"react": "^19.2.3"
|
|
35
39
|
},
|
|
36
|
-
"sideEffects":
|
|
40
|
+
"sideEffects": [
|
|
41
|
+
"./legacy.js"
|
|
42
|
+
]
|
|
37
43
|
}
|
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
import { type DataEngine, type LinkFilter, type RowPredicate, type ViewportEngine } from "@heswell/vuu-viewport";
|
|
2
2
|
import type { DataSourceBase, DataSourceConstructorProps, DataSourceEvents, DataSourceFilter, DataSourceRowWithBigint, DataSourceStatus, DataSourceSubscribeCallback, DataSourceSubscribeProps, TableSchema, WithBaseFilter, WithFullConfig } from "@vuu-ui/vuu-data-types";
|
|
3
3
|
import type { Filter } from "@vuu-ui/vuu-filter-types";
|
|
4
|
-
import type { LinkDescriptorWithLabel, SelectRequest, VuuAggregation, VuuGroupBy, VuuMenu, VuuRowDataItemType, VuuRpcMenuRequest, VuuRpcMenuResponse, VuuRpcServiceRequest, RpcResultError, RpcResultSuccess, VuuSort } from "@vuu-ui/vuu-protocol-types";
|
|
4
|
+
import type { LinkDescriptorWithLabel, SelectRequest, VuuAggregation, VuuGroupBy, VuuMenu, VuuRange, VuuRowDataItemType, VuuRpcMenuRequest, VuuRpcMenuResponse, VuuRpcServiceRequest, RpcResultError, RpcResultSuccess, VuuSort } from "@vuu-ui/vuu-protocol-types";
|
|
5
5
|
import type { ColumnDescriptor } from "@vuu-ui/vuu-table-types";
|
|
6
6
|
import { type ColumnMap, EventEmitter, Range } from "@vuu-ui/vuu-utils";
|
|
7
|
+
/**
|
|
8
|
+
* Accept either a vuu-utils `Range` or a plain `{from, to}` (VuuRange),
|
|
9
|
+
* which is converted to a `Range`.
|
|
10
|
+
*/
|
|
11
|
+
/** `range` may be a plain `{from, to}`. */
|
|
12
|
+
export type EngineDataSourceSubscribeProps = Omit<DataSourceSubscribeProps, "range"> & {
|
|
13
|
+
range?: Range | VuuRange;
|
|
14
|
+
};
|
|
15
|
+
export declare const toRange: (range: VuuRange | Range) => Range;
|
|
7
16
|
import { Table } from "./Table";
|
|
8
17
|
export interface EngineDataSourceConstructorProps extends Omit<DataSourceConstructorProps, "bufferSize" | "table"> {
|
|
9
18
|
/**
|
|
@@ -38,7 +47,7 @@ export declare class EngineDataSource extends EventEmitter<DataSourceEvents> imp
|
|
|
38
47
|
sendSizeUpdateToClient(): void;
|
|
39
48
|
/** Send every row in the current range, irrespective of what was sent before */
|
|
40
49
|
sendRowsToClient(): void;
|
|
41
|
-
subscribe({ viewport, columns, aggregations, baseFilterSpec, range, sort, groupBy, filterSpec, }:
|
|
50
|
+
subscribe({ viewport, columns, aggregations, baseFilterSpec, range, sort, groupBy, filterSpec, }: EngineDataSourceSubscribeProps, callback: DataSourceSubscribeCallback): Promise<void>;
|
|
42
51
|
unsubscribe(): void;
|
|
43
52
|
suspend(): void;
|
|
44
53
|
resume(callback?: DataSourceSubscribeCallback): void;
|
|
@@ -46,10 +55,11 @@ export declare class EngineDataSource extends EventEmitter<DataSourceEvents> imp
|
|
|
46
55
|
enable(): void;
|
|
47
56
|
get status(): DataSourceStatus;
|
|
48
57
|
get range(): Range;
|
|
58
|
+
/** A plain `{from, to}` is also accepted at runtime. */
|
|
49
59
|
set range(range: Range);
|
|
50
60
|
get maxRangeEnd(): number;
|
|
51
61
|
get pageSize(): number;
|
|
52
|
-
protected setRange(
|
|
62
|
+
protected setRange(vuuRange: Range | VuuRange, forceFullRefresh?: boolean): void;
|
|
53
63
|
get config(): WithBaseFilter<WithFullConfig>;
|
|
54
64
|
set config(config: WithBaseFilter<WithFullConfig>);
|
|
55
65
|
get aggregations(): VuuAggregation[];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { DataSourceBase, DataSource, DataSourceRowWithBigint, DataSourceSubscribeCallback,
|
|
1
|
+
import type { DataSourceBase, DataSource, DataSourceRowWithBigint, DataSourceSubscribeCallback, DataSourceVisualLinkCreatedMessage, DeleteRowMode, CopyOption, EditSessionMode, SessionDataSourceOverrides, SessionType } from "@vuu-ui/vuu-data-types";
|
|
2
2
|
import type { LinkDescriptorWithLabel, RpcResult, RpcResultError, RpcResultSuccess, VuuCreateVisualLink, VuuRemoveVisualLink, VuuRowDataItemType, VuuRpcMenuRequest, VuuRpcMenuResponse, VuuRpcServiceRequest } from "@vuu-ui/vuu-protocol-types";
|
|
3
3
|
import type { IVuuModule, RpcMenuService, RpcService } from "./core/module/VuuModule";
|
|
4
|
-
import { EngineDataSource, type EngineDataSourceConstructorProps } from "./EngineDataSource";
|
|
4
|
+
import { EngineDataSource, type EngineDataSourceConstructorProps, type EngineDataSourceSubscribeProps } from "./EngineDataSource";
|
|
5
5
|
export type VisualLinkHandler = (message: VuuCreateVisualLink | VuuRemoveVisualLink) => Promise<DataSourceVisualLinkCreatedMessage | undefined>;
|
|
6
6
|
export interface ModuleDataSourceConstructorProps extends EngineDataSourceConstructorProps {
|
|
7
7
|
getVisualLinks?: (tableName: string) => LinkDescriptorWithLabel[] | undefined;
|
|
@@ -18,7 +18,7 @@ export interface ModuleDataSourceConstructorProps extends EngineDataSourceConstr
|
|
|
18
18
|
export declare class ModuleDataSource extends EngineDataSource {
|
|
19
19
|
#private;
|
|
20
20
|
constructor({ getVisualLinks, rpcServices, rpcMenuServices, session, visualLink, visualLinkService, vuuModule, ...engineDataSourceProps }: ModuleDataSourceConstructorProps);
|
|
21
|
-
subscribe(subscribeProps:
|
|
21
|
+
subscribe(subscribeProps: EngineDataSourceSubscribeProps, callback: DataSourceSubscribeCallback): Promise<void>;
|
|
22
22
|
set links(links: LinkDescriptorWithLabel[] | undefined);
|
|
23
23
|
get links(): LinkDescriptorWithLabel[] | undefined;
|
|
24
24
|
isSessionDataSourceOf(dataSource: DataSource): boolean;
|
package/src/UpdateGenerator.d.ts
CHANGED
|
@@ -7,10 +7,22 @@ export declare class BaseUpdateGenerator implements UpdateGenerator {
|
|
|
7
7
|
private updating;
|
|
8
8
|
private timer;
|
|
9
9
|
private tickingColumns;
|
|
10
|
+
private enabled;
|
|
11
|
+
/**
|
|
12
|
+
* @param autoStart default true, start ticking as soon as a table and
|
|
13
|
+
* range are set. With false, ticking starts only when `start` is called.
|
|
14
|
+
*/
|
|
10
15
|
constructor(tickingColumns: {
|
|
11
16
|
[key: string]: number;
|
|
17
|
+
}, { autoStart }?: {
|
|
18
|
+
autoStart?: boolean;
|
|
12
19
|
});
|
|
13
20
|
setRange(range: VuuRange): void;
|
|
21
|
+
get isUpdating(): boolean;
|
|
22
|
+
/** Start (or resume) ticking. */
|
|
23
|
+
start(): void;
|
|
24
|
+
/** Stop ticking, clearing any pending timer. */
|
|
25
|
+
stop(): void;
|
|
14
26
|
setTable(table: Table): void;
|
|
15
27
|
private startUpdating;
|
|
16
28
|
private stopUpdating;
|
|
@@ -2,6 +2,15 @@ import type { VuuMenu } from "@vuu-ui/vuu-protocol-types";
|
|
|
2
2
|
import { type RpcMenuService, type ServiceHandler, VuuModule } from "../core/module/VuuModule";
|
|
3
3
|
import { type BasketsTableName } from "./basket-schemas";
|
|
4
4
|
import type { Table } from "../Table";
|
|
5
|
+
import { type PricesTable } from "../simul/reference-data/prices";
|
|
6
|
+
export type BasketModuleOptions = {
|
|
7
|
+
/**
|
|
8
|
+
* The prices table joined with basket constituents, typically the SIMUL
|
|
9
|
+
* module's prices (`simulModule.prices`). If not provided, the module
|
|
10
|
+
* creates its own prices table.
|
|
11
|
+
*/
|
|
12
|
+
prices?: PricesTable;
|
|
13
|
+
};
|
|
5
14
|
export declare const createBasketTradingRow: (basketId: string, basketName: string, side?: string, status?: string) => (string | number)[];
|
|
6
15
|
/**
|
|
7
16
|
* This is an example of how we might extend the built-in VuuModule to
|
|
@@ -10,7 +19,9 @@ export declare const createBasketTradingRow: (basketId: string, basketName: stri
|
|
|
10
19
|
*/
|
|
11
20
|
export declare class BasketModule extends VuuModule<BasketsTableName> {
|
|
12
21
|
#private;
|
|
13
|
-
constructor();
|
|
22
|
+
constructor({ prices }?: BasketModuleOptions);
|
|
23
|
+
protected beforeCreateDataSource(): void;
|
|
24
|
+
dispose(): void;
|
|
14
25
|
get menus(): Record<BasketsTableName, VuuMenu | undefined>;
|
|
15
26
|
get schemas(): Readonly<Record<BasketsTableName, Readonly<import("@vuu-ui/vuu-data-types").TableSchema>>>;
|
|
16
27
|
get services(): {
|
|
@@ -52,4 +63,3 @@ export declare class BasketModule extends VuuModule<BasketsTableName> {
|
|
|
52
63
|
private takeOffMarket;
|
|
53
64
|
private addConstituent;
|
|
54
65
|
}
|
|
55
|
-
export declare const basketModule: BasketModule;
|
package/src/basket/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { type BasketsTableName, schemas as basketSchemas, isBasketTable, } from "./basket-schemas";
|
|
2
|
-
export {
|
|
2
|
+
export { BasketModule, type BasketModuleOptions } from "./BasketModule";
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { DataSourceConfig, SessionDataSourceOverrides, TableSchema } from "@vuu-ui/vuu-data-types";
|
|
2
|
+
import type { VuuTable } from "@vuu-ui/vuu-protocol-types";
|
|
3
|
+
import type { VuuModule } from "../module/VuuModule";
|
|
4
|
+
import { TableContainer } from "../table/TableContainer";
|
|
5
|
+
export type AnyVuuModule = VuuModule<any>;
|
|
6
|
+
export interface LocalEngineOptions {
|
|
7
|
+
/** Modules to register on creation. */
|
|
8
|
+
modules?: AnyVuuModule[];
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* An in-browser Vuu server: a set of VuuModules and the tables they publish,
|
|
12
|
+
* keyed by `{module, table}`. Engines are fully isolated from each other, so
|
|
13
|
+
* two engines (or two modules in one engine) can use the same table names.
|
|
14
|
+
*
|
|
15
|
+
* The engine has no React or DOM dependency. Use `createDataSourceProvider`
|
|
16
|
+
* or `createLocalVuuServer` to expose it to a React app.
|
|
17
|
+
*/
|
|
18
|
+
export declare class LocalEngine {
|
|
19
|
+
#private;
|
|
20
|
+
readonly tableContainer: TableContainer;
|
|
21
|
+
constructor({ modules }?: LocalEngineOptions);
|
|
22
|
+
/**
|
|
23
|
+
* Register a module. A module already registered under the same name is
|
|
24
|
+
* replaced (and unregistered). Its tables are added to `tableContainer`,
|
|
25
|
+
* keyed by `{module: module.name, table}`.
|
|
26
|
+
*/
|
|
27
|
+
register<M extends AnyVuuModule>(module: M): M;
|
|
28
|
+
/** Remove a module and its tables. The module is not disposed. */
|
|
29
|
+
unregister(moduleName: string): boolean;
|
|
30
|
+
hasModule(moduleName: string): boolean;
|
|
31
|
+
getModule<M extends AnyVuuModule = AnyVuuModule>(moduleName: string): M;
|
|
32
|
+
get modules(): AnyVuuModule[];
|
|
33
|
+
get moduleNames(): string[];
|
|
34
|
+
/** Every table published by the registered modules. */
|
|
35
|
+
getTableList(): VuuTable[];
|
|
36
|
+
getTableSchema({ module, table }: VuuTable): TableSchema | undefined;
|
|
37
|
+
createDataSource({ module, table }: VuuTable, viewport?: string, config?: DataSourceConfig & {
|
|
38
|
+
session?: SessionDataSourceOverrides;
|
|
39
|
+
}): import("@vuu-ui/vuu-data-types").DataSourceBase<import("@vuu-ui/vuu-data-types").DataSourceRowWithBigint>;
|
|
40
|
+
get disposed(): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Unregister every module and dispose those owned by this engine (that is,
|
|
43
|
+
* first registered here), stopping any timers they started.
|
|
44
|
+
*/
|
|
45
|
+
dispose(): void;
|
|
46
|
+
}
|
|
47
|
+
/** Create an isolated local engine, optionally registering modules. */
|
|
48
|
+
export declare const createLocalEngine: (options?: LocalEngineOptions) => LocalEngine;
|
|
49
|
+
/**
|
|
50
|
+
* The shared engine behind the deprecated globals (`tableContainer`,
|
|
51
|
+
* `LocalDataSourceProvider`, `ensureVuuModule`) and the `/legacy` entry.
|
|
52
|
+
* Created on first use.
|
|
53
|
+
*/
|
|
54
|
+
export declare const getDefaultEngine: () => LocalEngine;
|
|
55
|
+
/** Dispose the default engine; the next `getDefaultEngine()` creates a new one. */
|
|
56
|
+
export declare const resetDefaultEngine: () => void;
|
|
57
|
+
/**
|
|
58
|
+
* Register a module with the default engine, unless a module with that name
|
|
59
|
+
* is already registered there.
|
|
60
|
+
* @deprecated create an engine with `createLocalEngine({ modules })`.
|
|
61
|
+
*/
|
|
62
|
+
export declare const ensureVuuModule: <T extends AnyVuuModule>(module: T) => T;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { VuuRowDataItemType } from "@vuu-ui/vuu-protocol-types";
|
|
2
2
|
import type { VuuModuleUser } from "../user/CurrentUser";
|
|
3
3
|
import type { ColumnMap } from "@vuu-ui/vuu-utils";
|
|
4
|
-
import type
|
|
4
|
+
import type { TableContainer } from "../table/TableContainer";
|
|
5
5
|
export type TableRow = Array<bigint | VuuRowDataItemType>;
|
|
6
6
|
export type RowPredicate = (row: TableRow) => boolean;
|
|
7
7
|
/**
|
|
@@ -29,7 +29,7 @@ export interface PermissionViewport {
|
|
|
29
29
|
id: string;
|
|
30
30
|
user: VuuModuleUser;
|
|
31
31
|
}
|
|
32
|
-
export type TableContainer
|
|
32
|
+
export type { TableContainer };
|
|
33
33
|
/**
|
|
34
34
|
* Creates the PermissionFilter for a viewport. Configured per table on a VuuModule.
|
|
35
35
|
*/
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import type { DataSourceBase, DataSourceConfig, DataSourceRowWithBigint, DataSourceSubscribedMessage, DataSourceVisualLinkCreatedMessage, EditSessionMode, CopyOption, SessionDataSourceOverrides, SessionType, TableSchema } from "@vuu-ui/vuu-data-types";
|
|
2
2
|
import type { VuuMenu, VuuLink, LinkDescriptorWithLabel, VuuRpcMenuResponse, VuuCreateVisualLink, VuuRemoveVisualLink, VuuRpcServiceRequest, RpcResultSuccess, RpcResultError, VuuRpcMenuRequest } from "@vuu-ui/vuu-protocol-types";
|
|
3
|
-
import { Table } from "../../Table";
|
|
3
|
+
import { Table, type TableRow } from "../../Table";
|
|
4
4
|
import { ModuleDataSource } from "../../ModuleDataSource";
|
|
5
5
|
import { type PermissionFunction } from "../filter/PermissionFilter";
|
|
6
6
|
import { type VuuModuleUser } from "../user/CurrentUser";
|
|
7
|
+
import { TableContainer } from "../table/TableContainer";
|
|
8
|
+
import type { LocalEngine } from "../engine/LocalEngine";
|
|
9
|
+
import { type CanSaveSessionResult, type CellEdit, type EditContext, type EditHooks, type PreparedSessionSave, type SessionRowChange, type SessionSaveResult } from "./edit-hooks";
|
|
7
10
|
export interface IVuuModule<T extends string = string> {
|
|
8
11
|
createDataSource: (tableName: T, viewport?: string, config?: DataSourceConfig & {
|
|
9
12
|
session?: SessionDataSourceOverrides;
|
|
@@ -39,16 +42,67 @@ type Subscription = {
|
|
|
39
42
|
};
|
|
40
43
|
export declare abstract class VuuModule<T extends string = string> implements IVuuModule<T> {
|
|
41
44
|
#private;
|
|
45
|
+
/**
|
|
46
|
+
* Modules are not registered anywhere on construction. Register them with
|
|
47
|
+
* a LocalEngine (`createLocalEngine({ modules })`).
|
|
48
|
+
*/
|
|
42
49
|
constructor(name: string, { sessionTableMessageColumn }?: VuuModuleOptions);
|
|
50
|
+
/** The engine this module was first registered with, if any. */
|
|
51
|
+
get engine(): LocalEngine | undefined;
|
|
52
|
+
/** @internal called by LocalEngine.register */
|
|
53
|
+
attachEngine(engine: LocalEngine): void;
|
|
54
|
+
/** @internal called by LocalEngine.unregister */
|
|
55
|
+
detachEngine(engine: LocalEngine): void;
|
|
56
|
+
/**
|
|
57
|
+
* Release resources (timers, providers). Called by `LocalEngine.dispose`
|
|
58
|
+
* for modules it owns. Subclasses that start timers should override,
|
|
59
|
+
* calling super.dispose().
|
|
60
|
+
*/
|
|
61
|
+
dispose(): void;
|
|
43
62
|
protected abstract menus?: Record<T, VuuMenu | undefined> | undefined;
|
|
44
63
|
protected abstract schemas: Record<T, Readonly<TableSchema>>;
|
|
45
64
|
protected abstract tables: Record<T, Table>;
|
|
46
65
|
protected abstract menuServices?: Record<T, RpcMenuService[] | undefined> | undefined;
|
|
66
|
+
/**
|
|
67
|
+
* Per table services. A service with the same rpcName as a built-in
|
|
68
|
+
* service (e.g. endEditSession, editCell) replaces it for that table,
|
|
69
|
+
* including for edit sessions created from the table.
|
|
70
|
+
*/
|
|
47
71
|
protected abstract services?: Record<T, RpcService[] | undefined> | undefined;
|
|
72
|
+
/**
|
|
73
|
+
* Services available on every table of this module. Like table services,
|
|
74
|
+
* these replace built-in services with the same rpcName. Table services
|
|
75
|
+
* take precedence.
|
|
76
|
+
*/
|
|
77
|
+
protected moduleServices?: RpcService[];
|
|
78
|
+
/**
|
|
79
|
+
* Per table edit hooks. These take precedence over the module-wide
|
|
80
|
+
* protected hook methods (isEditableColumn, validateCellEdit,
|
|
81
|
+
* getStaleColumns, canSaveSession, applySessionSave, canEditSource).
|
|
82
|
+
*/
|
|
83
|
+
protected editHooks?: Partial<Record<T, EditHooks>>;
|
|
48
84
|
protected abstract visualLinks?: Record<T, VuuLink[] | undefined>;
|
|
49
85
|
protected get includeDefaultServices(): boolean;
|
|
86
|
+
/**
|
|
87
|
+
* Called on save, before changes are prepared. Rows given a message
|
|
88
|
+
* (vuuMsg) here are treated as handled and excluded from the save.
|
|
89
|
+
* @deprecated implement applySessionSave (per table via editHooks).
|
|
90
|
+
*/
|
|
50
91
|
protected beforeSessionSave(_sourceTable: Table, _sessionTable: Table): Promise<void>;
|
|
92
|
+
/** Called after a successful save, before the session is reset. */
|
|
51
93
|
protected afterSessionSave(_sourceTable: Table, _sessionTable: Table): Promise<void>;
|
|
94
|
+
/** See {@link EditHooks.canEditSource}. Default true. */
|
|
95
|
+
protected canEditSource(_column: string, _ctx: EditContext): boolean;
|
|
96
|
+
/** See {@link EditHooks.isEditableColumn}. */
|
|
97
|
+
protected isEditableColumn(table: Table, column: string, _ctx: EditContext): boolean;
|
|
98
|
+
/** See {@link EditHooks.validateCellEdit}. */
|
|
99
|
+
protected validateCellEdit(_edit: CellEdit): string | undefined | void;
|
|
100
|
+
/** See {@link EditHooks.getStaleColumns}. */
|
|
101
|
+
protected getStaleColumns(sourceTable: Table, sourceRow: TableRow, change: SessionRowChange): string[];
|
|
102
|
+
/** See {@link EditHooks.canSaveSession}. Default true. */
|
|
103
|
+
protected canSaveSession(_prepared: PreparedSessionSave, _ctx: EditContext): CanSaveSessionResult | Promise<CanSaveSessionResult>;
|
|
104
|
+
/** See {@link EditHooks.applySessionSave}. */
|
|
105
|
+
protected applySessionSave(sessionTable: Table, prepared: PreparedSessionSave, _ctx: EditContext): SessionSaveResult | Promise<SessionSaveResult>;
|
|
52
106
|
/**
|
|
53
107
|
* Optional, per table. Restricts the rows visible to each viewport, based on
|
|
54
108
|
* the viewport (and the user who owns it).
|
|
@@ -61,6 +115,14 @@ export declare abstract class VuuModule<T extends string = string> implements IV
|
|
|
61
115
|
protected beforeCreateDataSource?(tableName: T): void;
|
|
62
116
|
getTableSchema(tableName: string): Record<T, Readonly<TableSchema>>[T];
|
|
63
117
|
getTableList(): string[];
|
|
118
|
+
/** The tables published by this module, keyed by table name. */
|
|
119
|
+
getTables(): Record<T, Table>;
|
|
120
|
+
getTable(tableName: T): Table;
|
|
121
|
+
/**
|
|
122
|
+
* Tables visible to permission functions: the engine's tables, or this
|
|
123
|
+
* module's own tables if it is not registered with an engine.
|
|
124
|
+
*/
|
|
125
|
+
protected get tableContainer(): TableContainer;
|
|
64
126
|
protected handlePostSubscribeActivities: ({ clientViewportId, tableSchema, }: DataSourceSubscribedMessage) => void;
|
|
65
127
|
protected unregisterViewport: (viewportId: string) => void;
|
|
66
128
|
get name(): string;
|
|
@@ -73,6 +135,11 @@ export declare abstract class VuuModule<T extends string = string> implements IV
|
|
|
73
135
|
session?: SessionDataSourceOverrides;
|
|
74
136
|
}) => DataSourceBase<DataSourceRowWithBigint>;
|
|
75
137
|
private createPermissionPredicate;
|
|
138
|
+
/**
|
|
139
|
+
* The RPC services for a table: built-in services, overridden by
|
|
140
|
+
* moduleServices, overridden by table services (matched by rpcName).
|
|
141
|
+
* For a session table, the services of its source table.
|
|
142
|
+
*/
|
|
76
143
|
getServices(tableName: T): RpcService[];
|
|
77
144
|
getMenuServices(tableName: T): RpcMenuService[];
|
|
78
145
|
protected get sessionTableMap(): SessionTableMap;
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import type { RpcResult, VuuColumnDataType, VuuRowDataItemType } from "@vuu-ui/vuu-protocol-types";
|
|
2
|
+
import type { Table, TableRow } from "../../Table";
|
|
3
|
+
import type { VuuModuleUser } from "../user/CurrentUser";
|
|
4
|
+
/**
|
|
5
|
+
* Engine-maintained columns. Not editable through editCell by default.
|
|
6
|
+
*/
|
|
7
|
+
export declare const VUU_SYSTEM_COLUMNS: ReadonlySet<string>;
|
|
8
|
+
export declare const isSystemColumn: (column: string) => boolean;
|
|
9
|
+
/**
|
|
10
|
+
* endEditSession error when a source row changed after it was copied into
|
|
11
|
+
* the session. vuu-ui's VuuDataSource matches this string exactly (and
|
|
12
|
+
* throws StaleUpdateError), do not change it.
|
|
13
|
+
*/
|
|
14
|
+
export declare const STALE_UPDATE = "stale update";
|
|
15
|
+
export declare const DUPLICATE_KEY = "duplicate key";
|
|
16
|
+
export declare const SAVE_NOT_PERMITTED = "endEditSession: save not permitted";
|
|
17
|
+
export declare const SAVE_FAILED = "endEditSession: save failed";
|
|
18
|
+
/**
|
|
19
|
+
* Passed to every edit hook.
|
|
20
|
+
*/
|
|
21
|
+
export interface EditContext {
|
|
22
|
+
moduleName: string;
|
|
23
|
+
/** The source table name (never the session table name). */
|
|
24
|
+
tableName: string;
|
|
25
|
+
/** The viewport that made the request. */
|
|
26
|
+
viewportId: string;
|
|
27
|
+
/** The user that owns the viewport. */
|
|
28
|
+
user: VuuModuleUser;
|
|
29
|
+
/** The session table, when the request targets an edit session. */
|
|
30
|
+
sessionTable?: Table;
|
|
31
|
+
sessionTableName?: string;
|
|
32
|
+
}
|
|
33
|
+
export type SessionTableAction = "addRow" | "editCell" | "deleteRow";
|
|
34
|
+
export type SessionRowChange = {
|
|
35
|
+
action: SessionTableAction;
|
|
36
|
+
/**
|
|
37
|
+
* Changed source columns and their new values. For addRow, every source
|
|
38
|
+
* column. Empty for deleteRow.
|
|
39
|
+
*/
|
|
40
|
+
cellUpdates: Record<string, VuuRowDataItemType>;
|
|
41
|
+
key: string;
|
|
42
|
+
/** The session row, projected onto the source table's columns. */
|
|
43
|
+
row: TableRow;
|
|
44
|
+
/** The session row, as stored in the session table. */
|
|
45
|
+
sessionRow: TableRow;
|
|
46
|
+
/**
|
|
47
|
+
* Copy of the source row taken when it was copied into the session (or
|
|
48
|
+
* when a change was undone). Used to detect concurrent source changes.
|
|
49
|
+
*/
|
|
50
|
+
sourceSnapshot?: TableRow;
|
|
51
|
+
};
|
|
52
|
+
export type PreparedSessionChange = SessionRowChange & {
|
|
53
|
+
/** The current source row (absent for addRow). */
|
|
54
|
+
sourceRow?: TableRow;
|
|
55
|
+
};
|
|
56
|
+
export type PreparedSessionSave = {
|
|
57
|
+
sourceTable: Table;
|
|
58
|
+
sessionTable: Table;
|
|
59
|
+
changes: PreparedSessionChange[];
|
|
60
|
+
};
|
|
61
|
+
/** true permits the save, false or a string (the reason) refuses it. */
|
|
62
|
+
export type CanSaveSessionResult = boolean | string;
|
|
63
|
+
/**
|
|
64
|
+
* undefined, true or a SUCCESS_RESULT mean the save succeeded. false or an
|
|
65
|
+
* ERROR_RESULT (as does a thrown error) mean it failed; the session is left
|
|
66
|
+
* open so the user can retry or cancel.
|
|
67
|
+
*/
|
|
68
|
+
export type SessionSaveResult = void | boolean | RpcResult;
|
|
69
|
+
/** A cell edit, passed to `validateCellEdit`. */
|
|
70
|
+
export type CellEdit = {
|
|
71
|
+
column: string;
|
|
72
|
+
ctx: EditContext;
|
|
73
|
+
dataType: VuuColumnDataType | undefined;
|
|
74
|
+
key: string;
|
|
75
|
+
/** the row after the edit */
|
|
76
|
+
newRow: TableRow;
|
|
77
|
+
/** the row before the edit */
|
|
78
|
+
row: TableRow;
|
|
79
|
+
/** the table being edited, the session table unless editing the source directly */
|
|
80
|
+
table: Table;
|
|
81
|
+
value: VuuRowDataItemType;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Edit and session-save hooks. Implement them as protected methods of a
|
|
85
|
+
* VuuModule (applying to every table), or per table via
|
|
86
|
+
* `VuuModule.editHooks`, which take precedence.
|
|
87
|
+
*/
|
|
88
|
+
export interface EditHooks {
|
|
89
|
+
/**
|
|
90
|
+
* Opt in to editCell on a viewport that is NOT using a session table, i.e.
|
|
91
|
+
* edits written directly to the source table. Default true (unlike
|
|
92
|
+
* vuu-server) for backward compatibility.
|
|
93
|
+
*/
|
|
94
|
+
canEditSource?: (column: string, ctx: EditContext) => boolean;
|
|
95
|
+
/**
|
|
96
|
+
* Whether a column may be edited through editCell. Default: any column
|
|
97
|
+
* except the key and the system columns.
|
|
98
|
+
*/
|
|
99
|
+
isEditableColumn?: (table: Table, column: string, ctx: EditContext) => boolean;
|
|
100
|
+
/** Return an error message to refuse a cell edit. */
|
|
101
|
+
validateCellEdit?: (edit: CellEdit) => string | undefined | void;
|
|
102
|
+
/**
|
|
103
|
+
* Names of the source columns that changed since the row was copied into
|
|
104
|
+
* the session. A non-empty result makes the save fail with "stale update".
|
|
105
|
+
*/
|
|
106
|
+
getStaleColumns?: (sourceTable: Table, sourceRow: TableRow, change: SessionRowChange) => string[];
|
|
107
|
+
/**
|
|
108
|
+
* Authorise a save, after changes are prepared (and found not stale),
|
|
109
|
+
* before applySessionSave. Return false or a reason to refuse.
|
|
110
|
+
*/
|
|
111
|
+
canSaveSession?: (prepared: PreparedSessionSave, ctx: EditContext) => CanSaveSessionResult | Promise<CanSaveSessionResult>;
|
|
112
|
+
/**
|
|
113
|
+
* Apply prepared changes. Default {@link defaultApplySessionSave}, an
|
|
114
|
+
* atomic write to the source table. Override to route changes elsewhere
|
|
115
|
+
* (e.g. to an order service); call `defaultApplySessionSave` for any
|
|
116
|
+
* changes that should still be written to the source table.
|
|
117
|
+
*/
|
|
118
|
+
applySessionSave?: (sessionTable: Table, prepared: PreparedSessionSave, ctx: EditContext) => SessionSaveResult | Promise<SessionSaveResult>;
|
|
119
|
+
}
|
|
120
|
+
export declare const defaultCanEditSource: () => boolean;
|
|
121
|
+
export declare const defaultIsEditableColumn: (table: Table, column: string) => boolean;
|
|
122
|
+
/**
|
|
123
|
+
* Compares the current source row with the snapshot taken when the row was
|
|
124
|
+
* copied into the session. For editCell, only the columns edited in the
|
|
125
|
+
* session are compared (other columns, e.g. ticking prices, are not written
|
|
126
|
+
* by the save so cannot conflict). For deleteRow, every column is compared.
|
|
127
|
+
* Without a snapshot (e.g. a row added to an empty session), nothing is
|
|
128
|
+
* reported as stale.
|
|
129
|
+
*/
|
|
130
|
+
export declare const defaultGetStaleColumns: (sourceTable: Table, sourceRow: TableRow, { action, cellUpdates, sourceSnapshot }: SessionRowChange) => string[];
|
|
131
|
+
/**
|
|
132
|
+
* Writes prepared changes to the source table. Atomic: if any change
|
|
133
|
+
* throws, changes already applied are rolled back and the error rethrown.
|
|
134
|
+
*/
|
|
135
|
+
export declare const defaultApplySessionSave: (_sessionTable: Table, { sourceTable, changes, }: Pick<PreparedSessionSave, "sourceTable" | "changes">) => SessionSaveResult;
|
|
@@ -3,19 +3,43 @@ import { Table } from "../../Table";
|
|
|
3
3
|
import type { VuuRowDataItemType, VuuTable } from "@vuu-ui/vuu-protocol-types";
|
|
4
4
|
import type { ColumnMap } from "@vuu-ui/vuu-utils";
|
|
5
5
|
import type { UpdateGenerator } from "../../rowUpdates";
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Create a table. The table is not registered anywhere; it belongs to
|
|
8
|
+
* whichever VuuModule returns it from `tables`.
|
|
9
|
+
*/
|
|
10
|
+
export declare const createTable: (schema: TableSchema, data?: Array<Array<VuuRowDataItemType | bigint>>, dataMap?: ColumnMap, updateGenerator?: UpdateGenerator) => Table;
|
|
11
|
+
/**
|
|
12
|
+
* Create a materialized (inner) join of two tables, backed by an engine
|
|
13
|
+
* JoinTable, maintained incrementally as either source changes.
|
|
14
|
+
*/
|
|
15
|
+
export declare const createJoinTable: (joinTable: VuuTable, table1: Table, table2: Table, joinColumn: string) => Table;
|
|
16
|
+
/**
|
|
17
|
+
* Tables, keyed by `{module, table}`. Each LocalEngine owns one, populated
|
|
18
|
+
* from the tables of its registered modules. Tables created through
|
|
19
|
+
* `createTable` / `createJoinTable` are added to this container.
|
|
20
|
+
*/
|
|
21
|
+
export declare class TableContainer {
|
|
7
22
|
#private;
|
|
8
|
-
private constructor();
|
|
9
|
-
static get instance(): TableContainer;
|
|
10
23
|
createTable: (schema: TableSchema, data?: Array<Array<VuuRowDataItemType | bigint>>, dataMap?: ColumnMap, updateGenerator?: UpdateGenerator) => Table;
|
|
11
24
|
/**
|
|
12
|
-
* Create a
|
|
13
|
-
*
|
|
14
|
-
* Both source tables must already have been created.
|
|
25
|
+
* Create a join of two tables already in this container. Pass full
|
|
26
|
+
* `{module, table}` references; a bare name is accepted only if unique.
|
|
15
27
|
*/
|
|
16
|
-
createJoinTable(joinTable: VuuTable,
|
|
17
|
-
|
|
18
|
-
|
|
28
|
+
createJoinTable(joinTable: VuuTable, table1: VuuTable | string, table2: VuuTable | string, joinColumn: string): Table;
|
|
29
|
+
/**
|
|
30
|
+
* Add a table, keyed by `as` if given, otherwise by its schema's
|
|
31
|
+
* `{module, table}`.
|
|
32
|
+
*/
|
|
33
|
+
addTable(table: Table, as?: VuuTable): void;
|
|
34
|
+
removeTable(table: VuuTable): boolean;
|
|
35
|
+
hasTable(table: VuuTable): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Resolve a table by `{module, table}`. A bare table name is accepted for
|
|
38
|
+
* backward compatibility, but only resolves if exactly one module has a
|
|
39
|
+
* table with that name.
|
|
40
|
+
*/
|
|
41
|
+
getTable(table: VuuTable | string): Table;
|
|
42
|
+
getTable<T>(table: VuuTable | string): T;
|
|
43
|
+
get tables(): Table[];
|
|
44
|
+
clear(): void;
|
|
19
45
|
}
|
|
20
|
-
declare const _default: TableContainer;
|
|
21
|
-
export default _default;
|
package/src/data-utils.d.ts
CHANGED
|
@@ -5,3 +5,10 @@ export declare const nextRandomDouble: PriceGenerator;
|
|
|
5
5
|
export declare const initBidAsk: (priceMaxDelta: number, nextRandomDouble: PriceGenerator) => number[];
|
|
6
6
|
export declare const generateNextBidAsk: (bid: number, ask: number, spreadMultipler: number, priceMaxDelta: number, nextRandomDouble: PriceGenerator) => number[];
|
|
7
7
|
export declare const withNanoMs: (ts: number, nanos?: number) => bigint;
|
|
8
|
+
/**
|
|
9
|
+
* Copy rows, so tables created from shared reference data do not share
|
|
10
|
+
* (and mutate) the same row arrays.
|
|
11
|
+
*/
|
|
12
|
+
export declare const cloneRows: <R extends unknown[]>(rows: readonly R[]) => R[];
|
|
13
|
+
/** Memoise a zero-arg factory. */
|
|
14
|
+
export declare const lazy: <V>(factory: () => V) => () => V;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { BasketModule } from "./basket/BasketModule";
|
|
2
|
+
import { type LocalEngine } from "./core/engine/LocalEngine";
|
|
3
|
+
import { SimulModule } from "./simul/SimulModule";
|
|
4
|
+
import { TestModule } from "./test/TestModule";
|
|
5
|
+
export type DemoModules = {
|
|
6
|
+
simulModule: SimulModule;
|
|
7
|
+
basketModule: BasketModule;
|
|
8
|
+
testModule: TestModule;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Create new SIMUL, BASKET and TEST demo modules and register them with an
|
|
12
|
+
* engine (by default, the default engine used by LocalDataSourceProvider).
|
|
13
|
+
* BASKET shares SIMUL's prices table. Prices tick only once a dataSource is
|
|
14
|
+
* created; `engine.dispose()` stops all timers.
|
|
15
|
+
*
|
|
16
|
+
* Nothing is created or registered until this is called.
|
|
17
|
+
*/
|
|
18
|
+
export declare const registerDemoModules: (engine?: LocalEngine) => DemoModules;
|
package/src/index.d.ts
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
export * from "./ArrayProxy";
|
|
2
2
|
export * from "./core/filter/PermissionFilter";
|
|
3
3
|
export * from "./core/module/VuuModule";
|
|
4
|
-
export
|
|
4
|
+
export * from "./core/module/edit-hooks";
|
|
5
|
+
export { type AnyVuuModule, createLocalEngine, ensureVuuModule, getDefaultEngine, LocalEngine, type LocalEngineOptions, resetDefaultEngine, } from "./core/engine/LocalEngine";
|
|
5
6
|
export * from "./core/user/CurrentUser";
|
|
6
|
-
export {
|
|
7
|
+
export { createJoinTable, createTable, TableContainer, } from "./core/table/TableContainer";
|
|
8
|
+
export { tableContainer } from "./core/table/defaultTableContainer";
|
|
9
|
+
export { registerDemoModules, type DemoModules } from "./demo-modules";
|
|
10
|
+
export { BaseUpdateGenerator } from "./UpdateGenerator";
|
|
7
11
|
export * from "./local-datasource-provider/LocalDatasourceProvider";
|
|
12
|
+
export { createDataSourceProvider } from "./local-datasource-provider/createDataSourceProvider";
|
|
8
13
|
export * from "./makeSuggestions";
|
|
9
14
|
export * from "./notifications";
|
|
10
15
|
export * from "./schemas";
|
package/src/legacy.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ModuleAdminModule } from "./module-admin/ModuleAdminModule";
|
|
2
|
+
import { UserAdminModule } from "./user-admin/UserAdminModule";
|
|
3
|
+
export * from "./index";
|
|
4
|
+
/** @deprecated */
|
|
5
|
+
export declare const simulModule: import("./simul").SimulModule, basketModule: import("./basket").BasketModule, testModule: import("./test").TestModule;
|
|
6
|
+
/** @deprecated */
|
|
7
|
+
export declare const moduleAdminModule: ModuleAdminModule;
|
|
8
|
+
/** @deprecated */
|
|
9
|
+
export declare const userAdminModule: UserAdminModule;
|
|
10
|
+
/** @deprecated */
|
|
11
|
+
export declare const notificationsModule: import("./notifications").NotificationModule;
|