@arcote.tech/arc-host 0.3.3 → 0.4.1
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/dist/index.d.ts +1 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1024 -364
- package/dist/index.js.map +12 -8
- package/dist/src/connection-manager.d.ts +16 -1
- package/dist/src/connection-manager.d.ts.map +1 -1
- package/dist/src/context-handler.d.ts +3 -5
- package/dist/src/context-handler.d.ts.map +1 -1
- package/dist/src/create-server.d.ts +36 -0
- package/dist/src/create-server.d.ts.map +1 -0
- package/dist/src/cron-scheduler.d.ts +30 -0
- package/dist/src/cron-scheduler.d.ts.map +1 -0
- package/dist/src/event-auth.d.ts +6 -1
- package/dist/src/event-auth.d.ts.map +1 -1
- package/dist/src/index.d.ts +6 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/middleware/http.d.ts +15 -0
- package/dist/src/middleware/http.d.ts.map +1 -0
- package/dist/src/middleware/index.d.ts +4 -0
- package/dist/src/middleware/index.d.ts.map +1 -0
- package/dist/src/middleware/types.d.ts +31 -0
- package/dist/src/middleware/types.d.ts.map +1 -0
- package/dist/src/middleware/ws.d.ts +9 -0
- package/dist/src/middleware/ws.d.ts.map +1 -0
- package/dist/src/types.d.ts +25 -4
- package/dist/src/types.d.ts.map +1 -1
- package/index.ts +2 -4
- package/package.json +2 -1
- package/src/connection-manager.ts +37 -7
- package/src/context-handler.ts +22 -23
- package/src/create-server.ts +213 -0
- package/src/cron-scheduler.ts +124 -0
- package/src/event-auth.ts +26 -1
- package/src/index.ts +39 -9
- package/src/middleware/http.ts +414 -0
- package/src/middleware/index.ts +27 -0
- package/src/middleware/types.ts +42 -0
- package/src/middleware/ws.ts +266 -0
- package/src/types.ts +22 -4
- package/dist/src/arc-host.d.ts +0 -75
- package/dist/src/arc-host.d.ts.map +0 -1
- package/src/arc-host.ts +0 -818
|
@@ -11,7 +11,7 @@ export declare class ConnectionManager {
|
|
|
11
11
|
*/
|
|
12
12
|
addClient(ws: ServerWebSocket<{
|
|
13
13
|
clientId: string;
|
|
14
|
-
}
|
|
14
|
+
}>): ConnectedClient;
|
|
15
15
|
/**
|
|
16
16
|
* Remove a client connection
|
|
17
17
|
*/
|
|
@@ -26,6 +26,21 @@ export declare class ConnectionManager {
|
|
|
26
26
|
getClientByWs(ws: ServerWebSocket<{
|
|
27
27
|
clientId: string;
|
|
28
28
|
}>): ConnectedClient | undefined;
|
|
29
|
+
/**
|
|
30
|
+
* Set a scope token for a client
|
|
31
|
+
*/
|
|
32
|
+
setScopeToken(clientId: string, scope: string, decoded: TokenPayload, raw: string): void;
|
|
33
|
+
/**
|
|
34
|
+
* Get a specific scope token for a client
|
|
35
|
+
*/
|
|
36
|
+
getScopeToken(clientId: string, scope: string): {
|
|
37
|
+
decoded: TokenPayload;
|
|
38
|
+
raw: string;
|
|
39
|
+
} | undefined;
|
|
40
|
+
/**
|
|
41
|
+
* Get all scope tokens for a client as an array of TokenPayload
|
|
42
|
+
*/
|
|
43
|
+
getAllScopeTokens(clientId: string): TokenPayload[];
|
|
29
44
|
/**
|
|
30
45
|
* Update client's last synced event ID
|
|
31
46
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection-manager.d.ts","sourceRoot":"","sources":["../../src/connection-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,KAAK,CAAC;AAC3C,OAAO,KAAK,EACV,eAAe,EACf,mBAAmB,EACnB,YAAY,EACb,MAAM,SAAS,CAAC;AAEjB;;GAEG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,OAAO,CAAsC;IACrD,OAAO,CAAC,eAAe,CAAK;IAE5B;;OAEG;IACH,SAAS,
|
|
1
|
+
{"version":3,"file":"connection-manager.d.ts","sourceRoot":"","sources":["../../src/connection-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,KAAK,CAAC;AAC3C,OAAO,KAAK,EACV,eAAe,EACf,mBAAmB,EACnB,YAAY,EACb,MAAM,SAAS,CAAC;AAEjB;;GAEG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,OAAO,CAAsC;IACrD,OAAO,CAAC,eAAe,CAAK;IAE5B;;OAEG;IACH,SAAS,CAAC,EAAE,EAAE,eAAe,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,eAAe;IAkBrE;;OAEG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAIpC;;OAEG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAIxD;;OAEG;IACH,aAAa,CACX,EAAE,EAAE,eAAe,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,GACxC,eAAe,GAAG,SAAS;IAM9B;;OAEG;IACH,aAAa,CACX,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,YAAY,EACrB,GAAG,EAAE,MAAM,GACV,IAAI;IAOP;;OAEG;IACH,aAAa,CACX,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GACZ;QAAE,OAAO,EAAE,YAAY,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS;IAKrD;;OAEG;IACH,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,EAAE;IAMnD;;OAEG;IACH,uBAAuB,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI;IAOpE;;OAEG;IACH,aAAa,IAAI,eAAe,EAAE;IAIlC;;OAEG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,GAAG,OAAO;IAarE;;OAEG;IACH,SAAS,CAAC,OAAO,EAAE,mBAAmB,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI;IAOvE;;OAEG;IACH,IAAI,WAAW,IAAI,MAAM,CAExB;CACF"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ArcContextAny, type ArcEventAny, type DatabaseAdapter, MasterDataStorage, Model } from "@arcote.tech/arc";
|
|
1
|
+
import { type ArcContextAny, type ArcEventAny, type DatabaseAdapter, LocalEventPublisher, MasterDataStorage, Model } from "@arcote.tech/arc";
|
|
2
2
|
import type { SyncableEvent, TokenPayload } from "./types";
|
|
3
3
|
/**
|
|
4
4
|
* Handles a single context on the host
|
|
@@ -8,7 +8,6 @@ export declare class ContextHandler {
|
|
|
8
8
|
private model;
|
|
9
9
|
private dataStorage;
|
|
10
10
|
private eventPublisher;
|
|
11
|
-
private authAdapter;
|
|
12
11
|
private eventDefinitions;
|
|
13
12
|
private hostEventIdCounter;
|
|
14
13
|
private initialized;
|
|
@@ -47,9 +46,8 @@ export declare class ContextHandler {
|
|
|
47
46
|
*/
|
|
48
47
|
getEventDefinitions(): Map<string, ArcEventAny>;
|
|
49
48
|
/**
|
|
50
|
-
*
|
|
51
|
-
* Used to apply view protection for queries
|
|
49
|
+
* Get event publisher for subscribing to data changes
|
|
52
50
|
*/
|
|
53
|
-
|
|
51
|
+
getEventPublisher(): LocalEventPublisher;
|
|
54
52
|
}
|
|
55
53
|
//# sourceMappingURL=context-handler.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-handler.d.ts","sourceRoot":"","sources":["../../src/context-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,WAAW,
|
|
1
|
+
{"version":3,"file":"context-handler.d.ts","sourceRoot":"","sources":["../../src/context-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,mBAAmB,EACnB,iBAAiB,EACjB,KAAK,EAGN,MAAM,kBAAkB,CAAC;AAE1B,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE3D;;GAEG;AACH,qBAAa,cAAc;aASP,OAAO,EAAE,aAAa;IARxC,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,WAAW,CAAoB;IACvC,OAAO,CAAC,cAAc,CAAsB;IAC5C,OAAO,CAAC,gBAAgB,CAAkC;IAC1D,OAAO,CAAC,kBAAkB,CAAK;IAC/B,OAAO,CAAC,WAAW,CAAS;gBAGV,OAAO,EAAE,aAAa,EACtC,SAAS,EAAE,OAAO,CAAC,eAAe,CAAC;IAqBrC;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAM3B;;OAEG;IACG,cAAc,CAClB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,GAAG,EACX,QAAQ,EAAE,MAAM,GAAG,IAAI,GACtB,OAAO,CAAC,GAAG,CAAC;IA8Bf;;OAEG;IACG,aAAa,CACjB,MAAM,EAAE,KAAK,CAAC;QACZ,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,GAAG,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC,EACF,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,YAAY,GAAG,IAAI,GACzB,OAAO,CAAC,aAAa,EAAE,CAAC;IA2C3B;;OAEG;IACG,cAAc,CAClB,eAAe,EAAE,MAAM,GAAG,IAAI,EAC9B,KAAK,EAAE,YAAY,GAAG,IAAI,GACzB,OAAO,CAAC,aAAa,EAAE,CAAC;IA8C3B;;OAEG;IACH,QAAQ,IAAI,KAAK,CAAC,aAAa,CAAC;IAIhC;;OAEG;IACH,cAAc,IAAI,iBAAiB;IAInC;;OAEG;IACH,mBAAmB,IAAI,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC;IAI/C;;OAEG;IACH,iBAAiB,IAAI,mBAAmB;CAGzC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { ArcContextAny, DatabaseAdapter } from "@arcote.tech/arc";
|
|
2
|
+
import type { Server } from "bun";
|
|
3
|
+
import { ConnectionManager } from "./connection-manager";
|
|
4
|
+
import { ContextHandler } from "./context-handler";
|
|
5
|
+
import { CronScheduler } from "./cron-scheduler";
|
|
6
|
+
import type { ArcHttpHandler, ArcWsHandler } from "./middleware/types";
|
|
7
|
+
type WebSocketData = {
|
|
8
|
+
clientId: string;
|
|
9
|
+
};
|
|
10
|
+
export interface ArcServerConfig {
|
|
11
|
+
context: ArcContextAny;
|
|
12
|
+
dbAdapterFactory: (ctx: any) => Promise<DatabaseAdapter>;
|
|
13
|
+
httpHandlers?: ArcHttpHandler[];
|
|
14
|
+
wsHandlers?: ArcWsHandler[];
|
|
15
|
+
port?: number;
|
|
16
|
+
jwtSecret?: string;
|
|
17
|
+
/** Extra callback when a WS client disconnects (e.g. to clean up platform state) */
|
|
18
|
+
onWsClose?: (clientId: string) => void;
|
|
19
|
+
}
|
|
20
|
+
export interface ArcServer {
|
|
21
|
+
server: Server<WebSocketData>;
|
|
22
|
+
contextHandler: ContextHandler;
|
|
23
|
+
connectionManager: ConnectionManager;
|
|
24
|
+
cronScheduler: CronScheduler;
|
|
25
|
+
stop: () => void;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Create an Arc server with composable HTTP + WS middleware.
|
|
29
|
+
*
|
|
30
|
+
* By default includes all Arc handlers (command, query, stream, route, eventSync, health,
|
|
31
|
+
* scope:auth, sync-events, request-sync, execute-command, view subscriptions).
|
|
32
|
+
* Platform servers add their own handlers on top.
|
|
33
|
+
*/
|
|
34
|
+
export declare function createArcServer(config: ArcServerConfig): Promise<ArcServer>;
|
|
35
|
+
export {};
|
|
36
|
+
//# sourceMappingURL=create-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-server.d.ts","sourceRoot":"","sources":["../../src/create-server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAElC,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAOjD,OAAO,KAAK,EACV,cAAc,EAGd,YAAY,EACb,MAAM,oBAAoB,CAAC;AAG5B,KAAK,aAAa,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1C,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,aAAa,CAAC;IACvB,gBAAgB,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;IACzD,YAAY,CAAC,EAAE,cAAc,EAAE,CAAC;IAChC,UAAU,CAAC,EAAE,YAAY,EAAE,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oFAAoF;IACpF,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC;IAC9B,cAAc,EAAE,cAAc,CAAC;IAC/B,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,aAAa,EAAE,aAAa,CAAC;IAC7B,IAAI,EAAE,MAAM,IAAI,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE,eAAe,GACtB,OAAO,CAAC,SAAS,CAAC,CAkKpB"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CronScheduler
|
|
3
|
+
*
|
|
4
|
+
* Discovers aggregate cron methods from context elements and schedules them
|
|
5
|
+
* using node-cron. For each cron trigger, queries all instances of the aggregate
|
|
6
|
+
* and executes the command for each instance.
|
|
7
|
+
*/
|
|
8
|
+
import type { ContextHandler } from "./context-handler";
|
|
9
|
+
export declare class CronScheduler {
|
|
10
|
+
private jobs;
|
|
11
|
+
private contextHandler;
|
|
12
|
+
constructor(contextHandler: ContextHandler);
|
|
13
|
+
/**
|
|
14
|
+
* Discover cron methods from all aggregates in the context and start scheduling.
|
|
15
|
+
*/
|
|
16
|
+
start(): void;
|
|
17
|
+
/**
|
|
18
|
+
* Stop all cron jobs.
|
|
19
|
+
*/
|
|
20
|
+
stop(): void;
|
|
21
|
+
/**
|
|
22
|
+
* Extract cron method entries from all aggregate context elements.
|
|
23
|
+
*/
|
|
24
|
+
private discoverCronMethods;
|
|
25
|
+
/**
|
|
26
|
+
* Execute a cron method for all instances of the aggregate.
|
|
27
|
+
*/
|
|
28
|
+
private executeCronMethod;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=cron-scheduler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cron-scheduler.d.ts","sourceRoot":"","sources":["../../src/cron-scheduler.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAOxD,qBAAa,aAAa;IACxB,OAAO,CAAC,IAAI,CAAiB;IAC7B,OAAO,CAAC,cAAc,CAAiB;gBAE3B,cAAc,EAAE,cAAc;IAI1C;;OAEG;IACH,KAAK,IAAI,IAAI;IAuBb;;OAEG;IACH,IAAI,IAAI,IAAI;IAQZ;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAe3B;;OAEG;YACW,iBAAiB;CAwChC"}
|
package/dist/src/event-auth.d.ts
CHANGED
|
@@ -13,7 +13,12 @@ export declare function canTokenReceiveEvent(token: TokenPayload | null, event:
|
|
|
13
13
|
*/
|
|
14
14
|
export declare function canTokenEmitEvent(token: TokenPayload | null, event: ArcEventAny, payload: any): boolean;
|
|
15
15
|
/**
|
|
16
|
-
* Filter events that a token can receive
|
|
16
|
+
* Filter events that a single token can receive
|
|
17
17
|
*/
|
|
18
18
|
export declare function filterEventsForToken(token: TokenPayload | null, events: SyncableEvent[], eventDefinitions: Map<string, ArcEventAny>): SyncableEvent[];
|
|
19
|
+
/**
|
|
20
|
+
* Filter events visible to ANY of the provided tokens.
|
|
21
|
+
* Used for multi-scope clients where an event visible to any scope should be sent.
|
|
22
|
+
*/
|
|
23
|
+
export declare function filterEventsForTokens(tokens: TokenPayload[], events: SyncableEvent[], eventDefinitions: Map<string, ArcEventAny>): SyncableEvent[];
|
|
19
24
|
//# sourceMappingURL=event-auth.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-auth.d.ts","sourceRoot":"","sources":["../../src/event-auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE3D;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,YAAY,GAAG,IAAI,EAC1B,KAAK,EAAE,WAAW,EAClB,aAAa,EAAE,aAAa,GAC3B,OAAO,CAqCT;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,YAAY,GAAG,IAAI,EAC1B,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,GAAG,GACX,OAAO,CA+BT;AAmBD;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,YAAY,GAAG,IAAI,EAC1B,MAAM,EAAE,aAAa,EAAE,EACvB,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,GACzC,aAAa,EAAE,CASjB"}
|
|
1
|
+
{"version":3,"file":"event-auth.d.ts","sourceRoot":"","sources":["../../src/event-auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE3D;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,YAAY,GAAG,IAAI,EAC1B,KAAK,EAAE,WAAW,EAClB,aAAa,EAAE,aAAa,GAC3B,OAAO,CAqCT;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,YAAY,GAAG,IAAI,EAC1B,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,GAAG,GACX,OAAO,CA+BT;AAmBD;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,YAAY,GAAG,IAAI,EAC1B,MAAM,EAAE,aAAa,EAAE,EACvB,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,GACzC,aAAa,EAAE,CASjB;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,YAAY,EAAE,EACtB,MAAM,EAAE,aAAa,EAAE,EACvB,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,GACzC,aAAa,EAAE,CAejB"}
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { createArcServer } from "./create-server";
|
|
2
|
+
export type { ArcServer, ArcServerConfig } from "./create-server";
|
|
3
|
+
export { arcHttpHandlers, arcWsHandlers, cleanupClientSubs, cleanupStreams, commandHandler, eventSyncHandler, executeCommandHandler, healthHandler, queryHandler, requestSyncHandler, routeHandler, scopeAuthHandler, streamHandler, syncEventsHandler, querySubscriptionHandler, } from "./middleware";
|
|
4
|
+
export type { ArcHttpHandler, ArcRequestContext, ArcWsContext, ArcWsHandler, } from "./middleware";
|
|
2
5
|
export { ConnectionManager } from "./connection-manager";
|
|
3
6
|
export { ContextHandler } from "./context-handler";
|
|
7
|
+
export { CronScheduler } from "./cron-scheduler";
|
|
8
|
+
export { canTokenEmitEvent, canTokenReceiveEvent, filterEventsForToken, filterEventsForTokens, } from "./event-auth";
|
|
4
9
|
export type { ArcHostConfig, ClientToHostMessage, ConnectedClient, HostToClientMessage, SyncableEvent, TokenPayload, } from "./types";
|
|
5
|
-
export { canTokenEmitEvent, canTokenReceiveEvent, filterEventsForToken, } from "./event-auth";
|
|
6
10
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAGlE,OAAO,EACL,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,qBAAqB,EACrB,aAAa,EACb,YAAY,EACZ,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,EAChB,aAAa,EACb,iBAAiB,EACjB,wBAAwB,GACzB,MAAM,cAAc,CAAC;AACtB,YAAY,EACV,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,YAAY,GACb,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGjD,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,cAAc,CAAC;AAGtB,YAAY,EACV,aAAa,EACb,mBAAmB,EACnB,eAAe,EACf,mBAAmB,EACnB,aAAa,EACb,YAAY,GACb,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ConnectionManager } from "../connection-manager";
|
|
2
|
+
import type { ContextHandler } from "../context-handler";
|
|
3
|
+
import type { ArcHttpHandler } from "./types";
|
|
4
|
+
export declare function healthHandler(cm: ConnectionManager): ArcHttpHandler;
|
|
5
|
+
export declare function commandHandler(ch: ContextHandler): ArcHttpHandler;
|
|
6
|
+
export declare function queryHandler(ch: ContextHandler): ArcHttpHandler;
|
|
7
|
+
export declare function streamHandler(ch: ContextHandler): ArcHttpHandler;
|
|
8
|
+
export declare function eventSyncHandler(ch: ContextHandler): ArcHttpHandler;
|
|
9
|
+
export declare function routeHandler(ch: ContextHandler): ArcHttpHandler;
|
|
10
|
+
export declare function arcHttpHandlers(ch: ContextHandler, cm: ConnectionManager): ArcHttpHandler[];
|
|
11
|
+
/**
|
|
12
|
+
* Cleanup all active SSE stream connections.
|
|
13
|
+
*/
|
|
14
|
+
export declare function cleanupStreams(): void;
|
|
15
|
+
//# sourceMappingURL=http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../src/middleware/http.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAqB,MAAM,SAAS,CAAC;AAoCjE,wBAAgB,aAAa,CAAC,EAAE,EAAE,iBAAiB,GAAG,cAAc,CAQnE;AAMD,wBAAgB,cAAc,CAAC,EAAE,EAAE,cAAc,GAAG,cAAc,CA+BjE;AAMD,wBAAgB,YAAY,CAAC,EAAE,EAAE,cAAc,GAAG,cAAc,CAoC/D;AAeD,wBAAgB,aAAa,CAAC,EAAE,EAAE,cAAc,GAAG,cAAc,CA+FhE;AAMD,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,cAAc,GAAG,cAAc,CA4BnE;AAMD,wBAAgB,YAAY,CAAC,EAAE,EAAE,cAAc,GAAG,cAAc,CA8G/D;AAMD,wBAAgB,eAAe,CAC7B,EAAE,EAAE,cAAc,EAClB,EAAE,EAAE,iBAAiB,GACpB,cAAc,EAAE,CASlB;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAGrC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export type { ArcHttpHandler, ArcRequestContext, ArcWsContext, ArcWsHandler, } from "./types";
|
|
2
|
+
export { arcHttpHandlers, cleanupStreams, commandHandler, eventSyncHandler, healthHandler, queryHandler, routeHandler, streamHandler, } from "./http";
|
|
3
|
+
export { arcWsHandlers, cleanupClientSubs, executeCommandHandler, requestSyncHandler, scopeAuthHandler, syncEventsHandler, querySubscriptionHandler, } from "./ws";
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/middleware/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,YAAY,GACb,MAAM,SAAS,CAAC;AAEjB,OAAO,EACL,eAAe,EACf,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,aAAa,GACd,MAAM,QAAQ,CAAC;AAEhB,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,qBAAqB,EACrB,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,wBAAwB,GACzB,MAAM,MAAM,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { ConnectionManager } from "../connection-manager";
|
|
2
|
+
import type { ContextHandler } from "../context-handler";
|
|
3
|
+
import type { ConnectedClient, TokenPayload } from "../types";
|
|
4
|
+
/**
|
|
5
|
+
* Per-request context passed to HTTP handlers.
|
|
6
|
+
* Created by createArcServer before running the handler chain.
|
|
7
|
+
*/
|
|
8
|
+
export interface ArcRequestContext {
|
|
9
|
+
rawToken: string | null;
|
|
10
|
+
tokenPayload: TokenPayload | null;
|
|
11
|
+
corsHeaders: Record<string, string>;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* HTTP middleware handler.
|
|
15
|
+
* Return a Response to stop the chain, or null to pass to the next handler.
|
|
16
|
+
*/
|
|
17
|
+
export type ArcHttpHandler = (req: Request, url: URL, ctx: ArcRequestContext) => Promise<Response | null> | Response | null;
|
|
18
|
+
/**
|
|
19
|
+
* Server context shared by all WS handlers.
|
|
20
|
+
*/
|
|
21
|
+
export interface ArcWsContext {
|
|
22
|
+
contextHandler: ContextHandler;
|
|
23
|
+
connectionManager: ConnectionManager;
|
|
24
|
+
verifyToken: (token: string) => TokenPayload | null;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* WebSocket message handler.
|
|
28
|
+
* Return true if handled, false to pass to the next handler.
|
|
29
|
+
*/
|
|
30
|
+
export type ArcWsHandler = (client: ConnectedClient, message: any, ctx: ArcWsContext) => Promise<boolean>;
|
|
31
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/middleware/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE9D;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,YAAY,EAAE,YAAY,GAAG,IAAI,CAAC;IAClC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC;AAED;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,CAC3B,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,iBAAiB,KACnB,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,QAAQ,GAAG,IAAI,CAAC;AAEhD;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,cAAc,EAAE,cAAc,CAAC;IAC/B,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,YAAY,GAAG,IAAI,CAAC;CACrD;AAED;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,CACzB,MAAM,EAAE,eAAe,EACvB,OAAO,EAAE,GAAG,EACZ,GAAG,EAAE,YAAY,KACd,OAAO,CAAC,OAAO,CAAC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ArcWsHandler } from "./types";
|
|
2
|
+
export declare function cleanupClientSubs(clientId: string): void;
|
|
3
|
+
export declare function scopeAuthHandler(): ArcWsHandler;
|
|
4
|
+
export declare function syncEventsHandler(): ArcWsHandler;
|
|
5
|
+
export declare function requestSyncHandler(): ArcWsHandler;
|
|
6
|
+
export declare function executeCommandHandler(): ArcWsHandler;
|
|
7
|
+
export declare function querySubscriptionHandler(): ArcWsHandler;
|
|
8
|
+
export declare function arcWsHandlers(): ArcWsHandler[];
|
|
9
|
+
//# sourceMappingURL=ws.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ws.d.ts","sourceRoot":"","sources":["../../../src/middleware/ws.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAgB,YAAY,EAAE,MAAM,SAAS,CAAC;AAQ1D,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAMxD;AAMD,wBAAgB,gBAAgB,IAAI,YAAY,CAc/C;AAMD,wBAAgB,iBAAiB,IAAI,YAAY,CAuChD;AAMD,wBAAgB,kBAAkB,IAAI,YAAY,CA+BjD;AAMD,wBAAgB,qBAAqB,IAAI,YAAY,CA6BpD;AAMD,wBAAgB,wBAAwB,IAAI,YAAY,CA2FvD;AAMD,wBAAgB,aAAa,IAAI,YAAY,EAAE,CAQ9C"}
|
package/dist/src/types.d.ts
CHANGED
|
@@ -33,10 +33,11 @@ export interface TokenPayload {
|
|
|
33
33
|
export interface ConnectedClient {
|
|
34
34
|
/** Unique client ID */
|
|
35
35
|
id: string;
|
|
36
|
-
/**
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
/** Scope tokens: Map<scope, { decoded, raw }> */
|
|
37
|
+
scopeTokens: Map<string, {
|
|
38
|
+
decoded: TokenPayload;
|
|
39
|
+
raw: string;
|
|
40
|
+
}>;
|
|
40
41
|
/** Last synced host event ID */
|
|
41
42
|
lastHostEventId: string | null;
|
|
42
43
|
/** WebSocket instance */
|
|
@@ -78,6 +79,22 @@ export type ClientToHostMessage = {
|
|
|
78
79
|
commandName: string;
|
|
79
80
|
params: any;
|
|
80
81
|
requestId: string;
|
|
82
|
+
} | {
|
|
83
|
+
type: "scope:auth";
|
|
84
|
+
scope: string;
|
|
85
|
+
token: string;
|
|
86
|
+
} | {
|
|
87
|
+
type: "subscribe-query";
|
|
88
|
+
subscriptionId: string;
|
|
89
|
+
descriptor: {
|
|
90
|
+
element: string;
|
|
91
|
+
method: string;
|
|
92
|
+
args: any[];
|
|
93
|
+
};
|
|
94
|
+
scope?: string;
|
|
95
|
+
} | {
|
|
96
|
+
type: "unsubscribe-query";
|
|
97
|
+
subscriptionId: string;
|
|
81
98
|
};
|
|
82
99
|
/**
|
|
83
100
|
* Messages from host to client
|
|
@@ -96,5 +113,9 @@ export type HostToClientMessage = {
|
|
|
96
113
|
} | {
|
|
97
114
|
type: "error";
|
|
98
115
|
message: string;
|
|
116
|
+
} | {
|
|
117
|
+
type: "query-data";
|
|
118
|
+
subscriptionId: string;
|
|
119
|
+
data: any[];
|
|
99
120
|
};
|
|
100
121
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/src/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAExE;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,uBAAuB;IACvB,OAAO,EAAE,aAAa,CAAC;IACvB,+BAA+B;IAC/B,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,kBAAkB;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0BAA0B;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,qCAAqC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,6CAA6C;IAC7C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,0BAA0B;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,2BAA2B;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,uBAAuB;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
|
package/index.ts
CHANGED
|
@@ -3,7 +3,7 @@ export * from "./src";
|
|
|
3
3
|
|
|
4
4
|
// Helper function to start host
|
|
5
5
|
import type { ArcContextAny, DBAdapterFactory } from "@arcote.tech/arc";
|
|
6
|
-
import {
|
|
6
|
+
import { createArcServer } from "./src/create-server";
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Start a host server for a context
|
|
@@ -12,10 +12,8 @@ export function hostLiveModel<C extends ArcContextAny>(
|
|
|
12
12
|
context: C,
|
|
13
13
|
dbAdapterFactory: DBAdapterFactory,
|
|
14
14
|
) {
|
|
15
|
-
|
|
15
|
+
return createArcServer({
|
|
16
16
|
context,
|
|
17
17
|
dbAdapterFactory,
|
|
18
18
|
});
|
|
19
|
-
host.start();
|
|
20
|
-
return host;
|
|
21
19
|
}
|
package/package.json
CHANGED
|
@@ -4,11 +4,12 @@
|
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"type": "module",
|
|
7
|
-
"version": "0.
|
|
7
|
+
"version": "0.4.1",
|
|
8
8
|
"private": false,
|
|
9
9
|
"author": "Przemysław Krasiński [arcote.tech]",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@arcote.tech/arc-adapter-db-sqlite": "^0.3.0",
|
|
12
|
+
"croner": "^9.0.0",
|
|
12
13
|
"jsonwebtoken": "^9.0.2"
|
|
13
14
|
},
|
|
14
15
|
"scripts": {
|
|
@@ -15,17 +15,12 @@ export class ConnectionManager {
|
|
|
15
15
|
/**
|
|
16
16
|
* Add a new client connection
|
|
17
17
|
*/
|
|
18
|
-
addClient(
|
|
19
|
-
ws: ServerWebSocket<{ clientId: string }>,
|
|
20
|
-
token: TokenPayload | null,
|
|
21
|
-
rawToken: string | null,
|
|
22
|
-
): ConnectedClient {
|
|
18
|
+
addClient(ws: ServerWebSocket<{ clientId: string }>): ConnectedClient {
|
|
23
19
|
const clientId = `client_${++this.clientIdCounter}_${Date.now()}`;
|
|
24
20
|
|
|
25
21
|
const client: ConnectedClient = {
|
|
26
22
|
id: clientId,
|
|
27
|
-
|
|
28
|
-
rawToken,
|
|
23
|
+
scopeTokens: new Map(),
|
|
29
24
|
lastHostEventId: null,
|
|
30
25
|
ws,
|
|
31
26
|
};
|
|
@@ -63,6 +58,41 @@ export class ConnectionManager {
|
|
|
63
58
|
return this.clients.get(clientId);
|
|
64
59
|
}
|
|
65
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Set a scope token for a client
|
|
63
|
+
*/
|
|
64
|
+
setScopeToken(
|
|
65
|
+
clientId: string,
|
|
66
|
+
scope: string,
|
|
67
|
+
decoded: TokenPayload,
|
|
68
|
+
raw: string,
|
|
69
|
+
): void {
|
|
70
|
+
const client = this.clients.get(clientId);
|
|
71
|
+
if (client) {
|
|
72
|
+
client.scopeTokens.set(scope, { decoded, raw });
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Get a specific scope token for a client
|
|
78
|
+
*/
|
|
79
|
+
getScopeToken(
|
|
80
|
+
clientId: string,
|
|
81
|
+
scope: string,
|
|
82
|
+
): { decoded: TokenPayload; raw: string } | undefined {
|
|
83
|
+
const client = this.clients.get(clientId);
|
|
84
|
+
return client?.scopeTokens.get(scope);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Get all scope tokens for a client as an array of TokenPayload
|
|
89
|
+
*/
|
|
90
|
+
getAllScopeTokens(clientId: string): TokenPayload[] {
|
|
91
|
+
const client = this.clients.get(clientId);
|
|
92
|
+
if (!client) return [];
|
|
93
|
+
return Array.from(client.scopeTokens.values()).map((v) => v.decoded);
|
|
94
|
+
}
|
|
95
|
+
|
|
66
96
|
/**
|
|
67
97
|
* Update client's last synced event ID
|
|
68
98
|
*/
|
package/src/context-handler.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
type ArcContextAny,
|
|
3
3
|
type ArcEventAny,
|
|
4
|
-
AuthAdapter,
|
|
5
4
|
type DatabaseAdapter,
|
|
6
5
|
LocalEventPublisher,
|
|
7
6
|
MasterDataStorage,
|
|
8
7
|
Model,
|
|
8
|
+
ScopedModel,
|
|
9
9
|
mutationExecutor,
|
|
10
10
|
} from "@arcote.tech/arc";
|
|
11
11
|
import { canTokenEmitEvent, filterEventsForToken } from "./event-auth";
|
|
@@ -18,7 +18,6 @@ export class ContextHandler {
|
|
|
18
18
|
private model: Model<ArcContextAny>;
|
|
19
19
|
private dataStorage: MasterDataStorage;
|
|
20
20
|
private eventPublisher: LocalEventPublisher;
|
|
21
|
-
private authAdapter: AuthAdapter;
|
|
22
21
|
private eventDefinitions = new Map<string, ArcEventAny>();
|
|
23
22
|
private hostEventIdCounter = 0;
|
|
24
23
|
private initialized = false;
|
|
@@ -29,13 +28,11 @@ export class ContextHandler {
|
|
|
29
28
|
) {
|
|
30
29
|
this.dataStorage = new MasterDataStorage(dbAdapter);
|
|
31
30
|
this.eventPublisher = new LocalEventPublisher(this.dataStorage);
|
|
32
|
-
this.authAdapter = new AuthAdapter();
|
|
33
31
|
|
|
34
32
|
this.model = new Model(context, {
|
|
35
33
|
adapters: {
|
|
36
34
|
dataStorage: this.dataStorage,
|
|
37
35
|
eventPublisher: this.eventPublisher,
|
|
38
|
-
authAdapter: this.authAdapter,
|
|
39
36
|
},
|
|
40
37
|
environment: "server",
|
|
41
38
|
});
|
|
@@ -65,28 +62,31 @@ export class ContextHandler {
|
|
|
65
62
|
params: any,
|
|
66
63
|
rawToken: string | null,
|
|
67
64
|
): Promise<any> {
|
|
68
|
-
|
|
69
|
-
const
|
|
65
|
+
// Create per-request scoped model with its own auth
|
|
66
|
+
const scoped = new ScopedModel(this.model, "request");
|
|
67
|
+
if (rawToken) scoped.setToken(rawToken);
|
|
68
|
+
|
|
69
|
+
const mutations = mutationExecutor(scoped);
|
|
70
|
+
|
|
71
|
+
// Support dotted names: "accounts.signIn" → mutations.accounts.signIn
|
|
72
|
+
let command: any;
|
|
73
|
+
if (commandName.includes(".")) {
|
|
74
|
+
const [elementName, methodName] = commandName.split(".");
|
|
75
|
+
const element = (mutations as any)[elementName];
|
|
76
|
+
command = element?.[methodName];
|
|
77
|
+
} else {
|
|
78
|
+
command = (mutations as any)[commandName];
|
|
79
|
+
}
|
|
70
80
|
|
|
71
81
|
if (!command) {
|
|
72
82
|
throw new Error(`Command '${commandName}' not found`);
|
|
73
83
|
}
|
|
74
84
|
|
|
75
|
-
// Set auth token on adapter so commands can access $auth.params
|
|
76
|
-
// AuthAdapter decodes the JWT internally
|
|
77
|
-
this.authAdapter.setToken(rawToken);
|
|
78
|
-
|
|
79
|
-
// TODO: Check command protection with token
|
|
80
|
-
|
|
81
85
|
try {
|
|
82
|
-
|
|
86
|
+
const result = await command(params);
|
|
87
|
+
return result;
|
|
83
88
|
} catch (error) {
|
|
84
|
-
console.error(`[ARC] Command '${commandName}' failed
|
|
85
|
-
console.error(`[ARC] Params:`, JSON.stringify(params, null, 2));
|
|
86
|
-
console.error(`[ARC] Error:`, error);
|
|
87
|
-
if (error instanceof Error) {
|
|
88
|
-
console.error(`[ARC] Stack:`, error.stack);
|
|
89
|
-
}
|
|
89
|
+
console.error(`[ARC] Command '${commandName}' failed:`, error);
|
|
90
90
|
throw error;
|
|
91
91
|
}
|
|
92
92
|
}
|
|
@@ -220,10 +220,9 @@ export class ContextHandler {
|
|
|
220
220
|
}
|
|
221
221
|
|
|
222
222
|
/**
|
|
223
|
-
*
|
|
224
|
-
* Used to apply view protection for queries
|
|
223
|
+
* Get event publisher for subscribing to data changes
|
|
225
224
|
*/
|
|
226
|
-
|
|
227
|
-
this.
|
|
225
|
+
getEventPublisher(): LocalEventPublisher {
|
|
226
|
+
return this.eventPublisher;
|
|
228
227
|
}
|
|
229
228
|
}
|