@arcote.tech/arc-host 0.1.11 → 0.3.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/dist/index.d.ts +8 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4433 -425
- package/dist/index.js.map +16 -14
- package/dist/sqliteAdapter.d.ts +1 -1
- package/dist/sqliteAdapter.d.ts.map +1 -1
- package/dist/src/arc-host.d.ts +69 -0
- package/dist/src/arc-host.d.ts.map +1 -0
- package/dist/src/connection-manager.d.ts +50 -0
- package/dist/src/connection-manager.d.ts.map +1 -0
- package/dist/src/context-handler.d.ts +55 -0
- package/dist/src/context-handler.d.ts.map +1 -0
- package/dist/src/event-auth.d.ts +19 -0
- package/dist/src/event-auth.d.ts.map +1 -0
- package/dist/src/index.d.ts +7 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/types.d.ts +100 -0
- package/dist/src/types.d.ts.map +1 -0
- package/index.ts +18 -7
- package/package.json +2 -1
- package/sqliteAdapter.ts +4 -29
- package/src/arc-host.ts +646 -0
- package/src/connection-manager.ts +115 -0
- package/src/context-handler.ts +219 -0
- package/src/event-auth.ts +127 -0
- package/src/index.ts +24 -0
- package/src/types.ts +112 -0
- package/dist/host.d.ts +0 -45
- package/dist/host.d.ts.map +0 -1
- package/dist/postgresAdapter.d.ts +0 -3
- package/dist/postgresAdapter.d.ts.map +0 -1
- package/host.ts +0 -510
- package/postgresAdapter.ts +0 -50
package/dist/sqliteAdapter.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqliteAdapter.d.ts","sourceRoot":"","sources":["../sqliteAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"sqliteAdapter.d.ts","sourceRoot":"","sources":["../sqliteAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAIzD,eAAO,MAAM,oBAAoB,GAAI,QAAQ,MAAM,KAAG,gBAErD,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { ArcHostConfig } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Arc Host - WebSocket server for real-time event sync
|
|
4
|
+
*/
|
|
5
|
+
export declare class ArcHost {
|
|
6
|
+
private config;
|
|
7
|
+
private server;
|
|
8
|
+
private connectionManager;
|
|
9
|
+
private contextHandler;
|
|
10
|
+
private streamConnections;
|
|
11
|
+
private jwtSecret;
|
|
12
|
+
private port;
|
|
13
|
+
private streamIdCounter;
|
|
14
|
+
constructor(config: ArcHostConfig);
|
|
15
|
+
/**
|
|
16
|
+
* Start the host server
|
|
17
|
+
*/
|
|
18
|
+
start(): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Verify JWT token
|
|
21
|
+
* Supports both standard JWT (jsonwebtoken) and Arc's custom JWT format
|
|
22
|
+
*/
|
|
23
|
+
private verifyToken;
|
|
24
|
+
/**
|
|
25
|
+
* Handle WebSocket message
|
|
26
|
+
*/
|
|
27
|
+
private handleMessage;
|
|
28
|
+
/**
|
|
29
|
+
* Handle sync-events message
|
|
30
|
+
*/
|
|
31
|
+
private handleSyncEvents;
|
|
32
|
+
/**
|
|
33
|
+
* Handle request-sync message (initial sync or catch-up)
|
|
34
|
+
*/
|
|
35
|
+
private handleRequestSync;
|
|
36
|
+
/**
|
|
37
|
+
* Handle execute-command message
|
|
38
|
+
*/
|
|
39
|
+
private handleExecuteCommand;
|
|
40
|
+
/**
|
|
41
|
+
* Send error to WebSocket
|
|
42
|
+
*/
|
|
43
|
+
private sendError;
|
|
44
|
+
/**
|
|
45
|
+
* Setup Bun server
|
|
46
|
+
*/
|
|
47
|
+
private setupServer;
|
|
48
|
+
/**
|
|
49
|
+
* Handle HTTP command request
|
|
50
|
+
*/
|
|
51
|
+
private handleHttpCommand;
|
|
52
|
+
/**
|
|
53
|
+
* Handle HTTP query request
|
|
54
|
+
*/
|
|
55
|
+
private handleHttpQuery;
|
|
56
|
+
/**
|
|
57
|
+
* Handle HTTP stream (SSE) request for live queries
|
|
58
|
+
*/
|
|
59
|
+
private handleHttpStream;
|
|
60
|
+
/**
|
|
61
|
+
* Handle HTTP event sync request
|
|
62
|
+
*/
|
|
63
|
+
private handleHttpEventSync;
|
|
64
|
+
/**
|
|
65
|
+
* Stop the server
|
|
66
|
+
*/
|
|
67
|
+
stop(): void;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=arc-host.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arc-host.d.ts","sourceRoot":"","sources":["../../src/arc-host.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,aAAa,EAId,MAAM,SAAS,CAAC;AAiBjB;;GAEG;AACH,qBAAa,OAAO;IASN,OAAO,CAAC,MAAM;IAR1B,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,iBAAiB,CAA2B;IACpD,OAAO,CAAC,cAAc,CAAkB;IACxC,OAAO,CAAC,iBAAiB,CAAuC;IAChE,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,eAAe,CAAK;gBAER,MAAM,EAAE,aAAa;IAQzC;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAS5B;;;OAGG;IACH,OAAO,CAAC,WAAW;IAuCnB;;OAEG;YACW,aAAa;IA4B3B;;OAEG;YACW,gBAAgB;IAgD9B;;OAEG;YACW,iBAAiB;IAkC/B;;OAEG;YACW,oBAAoB;IA0BlC;;OAEG;IACH,OAAO,CAAC,SAAS;IAIjB;;OAEG;IACH,OAAO,CAAC,WAAW;IA2InB;;OAEG;YACW,iBAAiB;IAiC/B;;OAEG;YACW,eAAe;IAiC7B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IA+GxB;;OAEG;YACW,mBAAmB;IA4CjC;;OAEG;IACH,IAAI,IAAI,IAAI;CASb"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { ServerWebSocket } from "bun";
|
|
2
|
+
import type { ConnectedClient, HostToClientMessage, TokenPayload } from "./types";
|
|
3
|
+
/**
|
|
4
|
+
* Manages WebSocket connections for a host
|
|
5
|
+
*/
|
|
6
|
+
export declare class ConnectionManager {
|
|
7
|
+
private clients;
|
|
8
|
+
private clientIdCounter;
|
|
9
|
+
/**
|
|
10
|
+
* Add a new client connection
|
|
11
|
+
*/
|
|
12
|
+
addClient(ws: ServerWebSocket<{
|
|
13
|
+
clientId: string;
|
|
14
|
+
}>, token: TokenPayload | null, rawToken: string | null): ConnectedClient;
|
|
15
|
+
/**
|
|
16
|
+
* Remove a client connection
|
|
17
|
+
*/
|
|
18
|
+
removeClient(clientId: string): void;
|
|
19
|
+
/**
|
|
20
|
+
* Get client by ID
|
|
21
|
+
*/
|
|
22
|
+
getClient(clientId: string): ConnectedClient | undefined;
|
|
23
|
+
/**
|
|
24
|
+
* Get client by WebSocket
|
|
25
|
+
*/
|
|
26
|
+
getClientByWs(ws: ServerWebSocket<{
|
|
27
|
+
clientId: string;
|
|
28
|
+
}>): ConnectedClient | undefined;
|
|
29
|
+
/**
|
|
30
|
+
* Update client's last synced event ID
|
|
31
|
+
*/
|
|
32
|
+
updateLastSyncedEventId(clientId: string, hostEventId: string): void;
|
|
33
|
+
/**
|
|
34
|
+
* Get all connected clients
|
|
35
|
+
*/
|
|
36
|
+
getAllClients(): ConnectedClient[];
|
|
37
|
+
/**
|
|
38
|
+
* Send message to a specific client
|
|
39
|
+
*/
|
|
40
|
+
sendToClient(clientId: string, message: HostToClientMessage): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Broadcast message to all clients
|
|
43
|
+
*/
|
|
44
|
+
broadcast(message: HostToClientMessage, excludeClientId?: string): void;
|
|
45
|
+
/**
|
|
46
|
+
* Get total number of connected clients
|
|
47
|
+
*/
|
|
48
|
+
get clientCount(): number;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=connection-manager.d.ts.map
|
|
@@ -0,0 +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,CACP,EAAE,EAAE,eAAe,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,EACzC,KAAK,EAAE,YAAY,GAAG,IAAI,EAC1B,QAAQ,EAAE,MAAM,GAAG,IAAI,GACtB,eAAe;IAmBlB;;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,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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { type ArcContextAny, type ArcEventAny, type DatabaseAdapter, MasterDataStorage, Model } from "@arcote.tech/arc";
|
|
2
|
+
import type { SyncableEvent, TokenPayload } from "./types";
|
|
3
|
+
/**
|
|
4
|
+
* Handles a single context on the host
|
|
5
|
+
*/
|
|
6
|
+
export declare class ContextHandler {
|
|
7
|
+
readonly context: ArcContextAny;
|
|
8
|
+
private model;
|
|
9
|
+
private dataStorage;
|
|
10
|
+
private eventPublisher;
|
|
11
|
+
private authAdapter;
|
|
12
|
+
private eventDefinitions;
|
|
13
|
+
private hostEventIdCounter;
|
|
14
|
+
private initialized;
|
|
15
|
+
constructor(context: ArcContextAny, dbAdapter: Promise<DatabaseAdapter>);
|
|
16
|
+
/**
|
|
17
|
+
* Initialize the context handler
|
|
18
|
+
*/
|
|
19
|
+
init(): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* Execute a command
|
|
22
|
+
*/
|
|
23
|
+
executeCommand(commandName: string, params: any, rawToken: string | null): Promise<any>;
|
|
24
|
+
/**
|
|
25
|
+
* Persist events from a client and return with host IDs
|
|
26
|
+
*/
|
|
27
|
+
persistEvents(events: Array<{
|
|
28
|
+
localId: string;
|
|
29
|
+
type: string;
|
|
30
|
+
payload: any;
|
|
31
|
+
createdAt: string;
|
|
32
|
+
}>, clientId: string, token: TokenPayload | null): Promise<SyncableEvent[]>;
|
|
33
|
+
/**
|
|
34
|
+
* Get events after a specific host ID, filtered by token
|
|
35
|
+
*/
|
|
36
|
+
getEventsSince(lastHostEventId: string | null, token: TokenPayload | null): Promise<SyncableEvent[]>;
|
|
37
|
+
/**
|
|
38
|
+
* Get the model for advanced operations
|
|
39
|
+
*/
|
|
40
|
+
getModel(): Model<ArcContextAny>;
|
|
41
|
+
/**
|
|
42
|
+
* Get data storage for queries
|
|
43
|
+
*/
|
|
44
|
+
getDataStorage(): MasterDataStorage;
|
|
45
|
+
/**
|
|
46
|
+
* Get event definitions map
|
|
47
|
+
*/
|
|
48
|
+
getEventDefinitions(): Map<string, ArcEventAny>;
|
|
49
|
+
/**
|
|
50
|
+
* Set auth token on the adapter
|
|
51
|
+
* Used to apply view protection for queries
|
|
52
|
+
*/
|
|
53
|
+
setAuthToken(rawToken: string | null): void;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=context-handler.d.ts.map
|
|
@@ -0,0 +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,EAEhB,KAAK,eAAe,EAEpB,iBAAiB,EACjB,KAAK,EAEN,MAAM,kBAAkB,CAAC;AAE1B,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE3D;;GAEG;AACH,qBAAa,cAAc;aAUP,OAAO,EAAE,aAAa;IATxC,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,WAAW,CAAoB;IACvC,OAAO,CAAC,cAAc,CAAsB;IAC5C,OAAO,CAAC,WAAW,CAAc;IACjC,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;IAuBrC;;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;IAiBf;;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;;;OAGG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;CAG5C"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ArcEventAny } from "@arcote.tech/arc";
|
|
2
|
+
import type { SyncableEvent, TokenPayload } from "./types";
|
|
3
|
+
/**
|
|
4
|
+
* Check if a token can receive an event based on explicit protectBy rules
|
|
5
|
+
*
|
|
6
|
+
* Security model:
|
|
7
|
+
* - Events WITHOUT protections: public, anyone can receive
|
|
8
|
+
* - Events WITH protections: MUST have matching read rule for token
|
|
9
|
+
*/
|
|
10
|
+
export declare function canTokenReceiveEvent(token: TokenPayload | null, event: ArcEventAny, eventInstance: SyncableEvent): boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Check if a token can emit an event
|
|
13
|
+
*/
|
|
14
|
+
export declare function canTokenEmitEvent(token: TokenPayload | null, event: ArcEventAny, payload: any): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Filter events that a token can receive
|
|
17
|
+
*/
|
|
18
|
+
export declare function filterEventsForToken(token: TokenPayload | null, events: SyncableEvent[], eventDefinitions: Map<string, ArcEventAny>): SyncableEvent[];
|
|
19
|
+
//# sourceMappingURL=event-auth.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { ArcHost } from "./arc-host";
|
|
2
|
+
export { ConnectionManager } from "./connection-manager";
|
|
3
|
+
export { ContextHandler } from "./context-handler";
|
|
4
|
+
export type { ArcHostConfig, ClientToHostMessage, ConnectedClient, HostToClientMessage, SyncableEvent, TokenPayload, } from "./types";
|
|
5
|
+
export { canTokenEmitEvent, canTokenReceiveEvent, filterEventsForToken, } from "./event-auth";
|
|
6
|
+
export { sqliteAdapterFactory } from "../sqliteAdapter";
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGnD,YAAY,EACV,aAAa,EACb,mBAAmB,EACnB,eAAe,EACf,mBAAmB,EACnB,aAAa,EACb,YAAY,GACb,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import type { ArcContextAny, DBAdapterFactory } from "@arcote.tech/arc";
|
|
2
|
+
/**
|
|
3
|
+
* Host configuration options
|
|
4
|
+
*/
|
|
5
|
+
export interface ArcHostConfig {
|
|
6
|
+
/** Context to serve */
|
|
7
|
+
context: ArcContextAny;
|
|
8
|
+
/** Database adapter factory */
|
|
9
|
+
dbAdapterFactory: DBAdapterFactory;
|
|
10
|
+
/** Server port */
|
|
11
|
+
port?: number;
|
|
12
|
+
/** JWT secret for token verification */
|
|
13
|
+
jwtSecret?: string;
|
|
14
|
+
/** JWT expiration time */
|
|
15
|
+
jwtExpiresIn?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Token payload from JWT
|
|
19
|
+
*/
|
|
20
|
+
export interface TokenPayload {
|
|
21
|
+
/** Token type name (e.g., "user") */
|
|
22
|
+
tokenType: string;
|
|
23
|
+
/** Token params (e.g., { userId: "123" }) */
|
|
24
|
+
params: Record<string, any>;
|
|
25
|
+
/** Issued at timestamp */
|
|
26
|
+
iat?: number;
|
|
27
|
+
/** Expiration timestamp */
|
|
28
|
+
exp?: number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Connected client info
|
|
32
|
+
*/
|
|
33
|
+
export interface ConnectedClient {
|
|
34
|
+
/** Unique client ID */
|
|
35
|
+
id: string;
|
|
36
|
+
/** Token payload (decoded) */
|
|
37
|
+
token: TokenPayload | null;
|
|
38
|
+
/** Raw JWT token string */
|
|
39
|
+
rawToken: string | null;
|
|
40
|
+
/** Last synced host event ID */
|
|
41
|
+
lastHostEventId: string | null;
|
|
42
|
+
/** WebSocket instance */
|
|
43
|
+
ws: any;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Event with sync IDs
|
|
47
|
+
*/
|
|
48
|
+
export interface SyncableEvent {
|
|
49
|
+
/** Local ID generated by client */
|
|
50
|
+
localId: string;
|
|
51
|
+
/** Host ID assigned when persisted */
|
|
52
|
+
hostId: string;
|
|
53
|
+
/** Event type */
|
|
54
|
+
type: string;
|
|
55
|
+
/** Event payload */
|
|
56
|
+
payload: any;
|
|
57
|
+
/** Creation timestamp */
|
|
58
|
+
createdAt: string;
|
|
59
|
+
/** Client ID that created this event */
|
|
60
|
+
clientId: string;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Messages from client to host
|
|
64
|
+
*/
|
|
65
|
+
export type ClientToHostMessage = {
|
|
66
|
+
type: "sync-events";
|
|
67
|
+
events: Array<{
|
|
68
|
+
localId: string;
|
|
69
|
+
type: string;
|
|
70
|
+
payload: any;
|
|
71
|
+
createdAt: string;
|
|
72
|
+
}>;
|
|
73
|
+
} | {
|
|
74
|
+
type: "request-sync";
|
|
75
|
+
lastHostEventId: string | null;
|
|
76
|
+
} | {
|
|
77
|
+
type: "execute-command";
|
|
78
|
+
commandName: string;
|
|
79
|
+
params: any;
|
|
80
|
+
requestId: string;
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* Messages from host to client
|
|
84
|
+
*/
|
|
85
|
+
export type HostToClientMessage = {
|
|
86
|
+
type: "events";
|
|
87
|
+
events: SyncableEvent[];
|
|
88
|
+
} | {
|
|
89
|
+
type: "command-result";
|
|
90
|
+
requestId: string;
|
|
91
|
+
result?: any;
|
|
92
|
+
error?: string;
|
|
93
|
+
} | {
|
|
94
|
+
type: "sync-complete";
|
|
95
|
+
lastHostEventId: string;
|
|
96
|
+
} | {
|
|
97
|
+
type: "error";
|
|
98
|
+
message: string;
|
|
99
|
+
};
|
|
100
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +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,8BAA8B;IAC9B,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;IAC3B,2BAA2B;IAC3B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,gCAAgC;IAChC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,yBAAyB;IACzB,EAAE,EAAE,GAAG,CAAC;CACT;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,sCAAsC;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,iBAAiB;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,oBAAoB;IACpB,OAAO,EAAE,GAAG,CAAC;IACb,yBAAyB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,wCAAwC;IACxC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAC3B;IACE,IAAI,EAAE,aAAa,CAAC;IACpB,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,CAAC;CACJ,GACD;IACE,IAAI,EAAE,cAAc,CAAC;IACrB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC,GACD;IACE,IAAI,EAAE,iBAAiB,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,GAAG,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEN;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAC3B;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,aAAa,EAAE,CAAC;CACzB,GACD;IACE,IAAI,EAAE,gBAAgB,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GACD;IACE,IAAI,EAAE,eAAe,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;CACzB,GACD;IACE,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC"}
|
package/index.ts
CHANGED
|
@@ -1,13 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import { sqliteAdapterFactory } from "./sqliteAdapter";
|
|
1
|
+
// Re-export everything from src
|
|
2
|
+
export * from "./src";
|
|
4
3
|
|
|
5
|
-
|
|
4
|
+
// Legacy export for backwards compatibility
|
|
5
|
+
export { sqliteAdapterFactory } from "./sqliteAdapter";
|
|
6
6
|
|
|
7
|
+
// Helper function to start host
|
|
8
|
+
import type { ArcContextAny, DBAdapterFactory } from "@arcote.tech/arc";
|
|
9
|
+
import { ArcHost } from "./src/arc-host";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Start a host server for a context
|
|
13
|
+
*/
|
|
7
14
|
export function hostLiveModel<C extends ArcContextAny>(
|
|
8
15
|
context: C,
|
|
9
|
-
|
|
16
|
+
dbAdapterFactory: DBAdapterFactory,
|
|
10
17
|
) {
|
|
11
|
-
const
|
|
12
|
-
|
|
18
|
+
const host = new ArcHost({
|
|
19
|
+
context,
|
|
20
|
+
dbAdapterFactory,
|
|
21
|
+
});
|
|
22
|
+
host.start();
|
|
23
|
+
return host;
|
|
13
24
|
}
|
package/package.json
CHANGED
|
@@ -4,10 +4,11 @@
|
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"type": "module",
|
|
7
|
-
"version": "0.
|
|
7
|
+
"version": "0.3.0",
|
|
8
8
|
"private": false,
|
|
9
9
|
"author": "Przemysław Krasiński [arcote.tech]",
|
|
10
10
|
"dependencies": {
|
|
11
|
+
"@arcote.tech/arc-adapter-db-sqlite": "workspace:*",
|
|
11
12
|
"jsonwebtoken": "^9.0.2"
|
|
12
13
|
},
|
|
13
14
|
"scripts": {
|
package/sqliteAdapter.ts
CHANGED
|
@@ -1,32 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
type DBAdapterFactory,
|
|
5
|
-
type SQLiteDatabase,
|
|
6
|
-
} from "@arcote.tech/arc";
|
|
7
|
-
import { Database } from "bun:sqlite";
|
|
8
|
-
|
|
9
|
-
class BunSQLiteDatabase implements SQLiteDatabase {
|
|
10
|
-
constructor(private db: Database) {}
|
|
11
|
-
|
|
12
|
-
async exec(sql: string, params?: any[]): Promise<any> {
|
|
13
|
-
try {
|
|
14
|
-
if (params && params.length > 0) {
|
|
15
|
-
const stmt = this.db.prepare(sql);
|
|
16
|
-
return stmt.all(...params);
|
|
17
|
-
}
|
|
18
|
-
return this.db.query(sql).all();
|
|
19
|
-
} catch (error) {
|
|
20
|
-
console.error("SQLite error:", error);
|
|
21
|
-
throw error;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
}
|
|
1
|
+
import type { DBAdapterFactory } from "@arcote.tech/arc";
|
|
2
|
+
// @ts-ignore - external package without types
|
|
3
|
+
import { createBunSQLiteAdapterFactory } from "@arcote.tech/arc-adapter-db-sqlite";
|
|
25
4
|
|
|
26
5
|
export const sqliteAdapterFactory = (dbName: string): DBAdapterFactory => {
|
|
27
|
-
return
|
|
28
|
-
const db = new Database(dbName);
|
|
29
|
-
const sqliteDb = new BunSQLiteDatabase(db);
|
|
30
|
-
return createSQLiteAdapterFactory(sqliteDb)(context);
|
|
31
|
-
};
|
|
6
|
+
return createBunSQLiteAdapterFactory(dbName);
|
|
32
7
|
};
|