@concavejs/runtime-cf-base 0.0.1-alpha.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/dist/adapters/cf-websocket-adapter.d.ts +38 -0
  2. package/dist/adapters/cf-websocket-adapter.js +83 -0
  3. package/dist/durable-objects/blobstore-rpc.d.ts +13 -0
  4. package/dist/durable-objects/blobstore-rpc.js +27 -0
  5. package/dist/durable-objects/concave-do-base.d.ts +169 -0
  6. package/dist/durable-objects/concave-do-base.js +466 -0
  7. package/dist/durable-objects/docstore-rpc.d.ts +46 -0
  8. package/dist/durable-objects/docstore-rpc.js +63 -0
  9. package/dist/durable-objects/scheduler-manager.d.ts +19 -0
  10. package/dist/durable-objects/scheduler-manager.js +53 -0
  11. package/dist/durable-objects/sync-notifier.d.ts +16 -0
  12. package/dist/durable-objects/sync-notifier.js +38 -0
  13. package/dist/env.d.ts +19 -0
  14. package/dist/env.js +6 -0
  15. package/dist/http/dx-http.d.ts +43 -0
  16. package/dist/http/dx-http.js +327 -0
  17. package/dist/http/http-api.d.ts +38 -0
  18. package/dist/http/http-api.js +399 -0
  19. package/dist/http/index.d.ts +7 -0
  20. package/dist/http/index.js +7 -0
  21. package/dist/index.d.ts +18 -0
  22. package/dist/index.js +27 -0
  23. package/dist/internal.d.ts +4 -0
  24. package/dist/internal.js +4 -0
  25. package/dist/routing/instance.d.ts +25 -0
  26. package/dist/routing/instance.js +101 -0
  27. package/dist/routing/sync-topology.d.ts +40 -0
  28. package/dist/routing/sync-topology.js +669 -0
  29. package/dist/rpc/blobstore-proxy.d.ts +11 -0
  30. package/dist/rpc/blobstore-proxy.js +28 -0
  31. package/dist/rpc/docstore-proxy.d.ts +11 -0
  32. package/dist/rpc/docstore-proxy.js +73 -0
  33. package/dist/rpc/index.d.ts +2 -0
  34. package/dist/rpc/index.js +2 -0
  35. package/dist/sync/cf-websocket-adapter.d.ts +15 -0
  36. package/dist/sync/cf-websocket-adapter.js +22 -0
  37. package/dist/sync/concave-do-udf-executor.d.ts +46 -0
  38. package/dist/sync/concave-do-udf-executor.js +75 -0
  39. package/dist/sync/index.d.ts +2 -0
  40. package/dist/sync/index.js +2 -0
  41. package/dist/udf/executor/do-client-executor.d.ts +14 -0
  42. package/dist/udf/executor/do-client-executor.js +58 -0
  43. package/dist/udf/executor/index.d.ts +8 -0
  44. package/dist/udf/executor/index.js +8 -0
  45. package/dist/udf/executor/inline-executor.d.ts +13 -0
  46. package/dist/udf/executor/inline-executor.js +25 -0
  47. package/dist/udf/executor/isolated-executor.d.ts +24 -0
  48. package/dist/udf/executor/isolated-executor.js +31 -0
  49. package/dist/udf/executor/shim-content.d.ts +1 -0
  50. package/dist/udf/executor/shim-content.js +3 -0
  51. package/dist/worker/create-concave-worker.d.ts +79 -0
  52. package/dist/worker/create-concave-worker.js +196 -0
  53. package/dist/worker/index.d.ts +6 -0
  54. package/dist/worker/index.js +6 -0
  55. package/dist/worker/udf-worker.d.ts +25 -0
  56. package/dist/worker/udf-worker.js +63 -0
  57. package/package.json +99 -0
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Cloudflare WebSocket Adapter
3
+ *
4
+ * Adapts Cloudflare Workers WebSocket to the platform-agnostic WebSocketConnection interface
5
+ */
6
+ import { type WebSocketConnection, WebSocketReadyState, type WebSocketMessageHandler, type WebSocketCloseHandler, type WebSocketErrorHandler } from "@concavejs/core/abstractions";
7
+ export declare class CFWebSocketAdapter implements WebSocketConnection {
8
+ private ws;
9
+ private messageHandlers;
10
+ private closeHandlers;
11
+ private errorHandlers;
12
+ constructor(ws: WebSocket);
13
+ get readyState(): WebSocketReadyState;
14
+ send(data: string | ArrayBuffer): void;
15
+ close(code?: number, reason?: string): void;
16
+ onMessage(handler: WebSocketMessageHandler): void;
17
+ onClose(handler: WebSocketCloseHandler): void;
18
+ onError(handler: WebSocketErrorHandler): void;
19
+ /**
20
+ * Internal method to trigger message handlers
21
+ * Call this from your Durable Object's webSocketMessage handler
22
+ */
23
+ triggerMessage(data: string | ArrayBuffer): void;
24
+ /**
25
+ * Internal method to trigger close handlers
26
+ * Call this from your Durable Object's webSocketClose handler
27
+ */
28
+ triggerClose(code?: number, reason?: string): void;
29
+ /**
30
+ * Internal method to trigger error handlers
31
+ * Call this from your Durable Object's webSocketError handler
32
+ */
33
+ triggerError(error: Error): void;
34
+ /**
35
+ * Get the underlying Cloudflare WebSocket
36
+ */
37
+ get underlying(): WebSocket;
38
+ }
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Cloudflare WebSocket Adapter
3
+ *
4
+ * Adapts Cloudflare Workers WebSocket to the platform-agnostic WebSocketConnection interface
5
+ */
6
+ import { WebSocketReadyState, } from "@concavejs/core/abstractions";
7
+ export class CFWebSocketAdapter {
8
+ ws;
9
+ messageHandlers = [];
10
+ closeHandlers = [];
11
+ errorHandlers = [];
12
+ constructor(ws) {
13
+ this.ws = ws;
14
+ }
15
+ get readyState() {
16
+ // Map CF WebSocket ready states to our enum
17
+ switch (this.ws.readyState) {
18
+ case WebSocket.READY_STATE_CONNECTING:
19
+ return WebSocketReadyState.CONNECTING;
20
+ case WebSocket.READY_STATE_OPEN:
21
+ return WebSocketReadyState.OPEN;
22
+ case WebSocket.READY_STATE_CLOSING:
23
+ return WebSocketReadyState.CLOSING;
24
+ case WebSocket.READY_STATE_CLOSED:
25
+ return WebSocketReadyState.CLOSED;
26
+ default:
27
+ return WebSocketReadyState.CLOSED;
28
+ }
29
+ }
30
+ send(data) {
31
+ this.ws.send(data);
32
+ }
33
+ close(code, reason) {
34
+ if (code !== undefined) {
35
+ this.ws.close(code, reason);
36
+ }
37
+ else {
38
+ this.ws.close();
39
+ }
40
+ }
41
+ onMessage(handler) {
42
+ this.messageHandlers.push(handler);
43
+ }
44
+ onClose(handler) {
45
+ this.closeHandlers.push(handler);
46
+ }
47
+ onError(handler) {
48
+ this.errorHandlers.push(handler);
49
+ }
50
+ /**
51
+ * Internal method to trigger message handlers
52
+ * Call this from your Durable Object's webSocketMessage handler
53
+ */
54
+ triggerMessage(data) {
55
+ for (const handler of this.messageHandlers) {
56
+ handler(data);
57
+ }
58
+ }
59
+ /**
60
+ * Internal method to trigger close handlers
61
+ * Call this from your Durable Object's webSocketClose handler
62
+ */
63
+ triggerClose(code, reason) {
64
+ for (const handler of this.closeHandlers) {
65
+ handler(code, reason);
66
+ }
67
+ }
68
+ /**
69
+ * Internal method to trigger error handlers
70
+ * Call this from your Durable Object's webSocketError handler
71
+ */
72
+ triggerError(error) {
73
+ for (const handler of this.errorHandlers) {
74
+ handler(error);
75
+ }
76
+ }
77
+ /**
78
+ * Get the underlying Cloudflare WebSocket
79
+ */
80
+ get underlying() {
81
+ return this.ws;
82
+ }
83
+ }
@@ -0,0 +1,13 @@
1
+ import type { BlobStore, StorageOptions, StorageMetadata } from "@concavejs/core/abstractions";
2
+ /**
3
+ * BlobStore RPC surface for service-binding isolation.
4
+ * Provides async delegation methods for blob storage operations.
5
+ */
6
+ export declare class BlobStoreRpc {
7
+ private readonly blobstore;
8
+ constructor(blobstore: BlobStore);
9
+ store(buffer: ArrayBuffer, options?: StorageOptions): Promise<StorageMetadata>;
10
+ get(storageId: string): Promise<ArrayBuffer | null>;
11
+ delete(storageId: string): Promise<void>;
12
+ getUrl(storageId: string): Promise<string | null>;
13
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * BlobStore RPC surface for service-binding isolation.
3
+ * Provides async delegation methods for blob storage operations.
4
+ */
5
+ export class BlobStoreRpc {
6
+ blobstore;
7
+ constructor(blobstore) {
8
+ this.blobstore = blobstore;
9
+ }
10
+ async store(buffer, options) {
11
+ return this.blobstore.store(buffer, options);
12
+ }
13
+ async get(storageId) {
14
+ const result = await this.blobstore.get(storageId);
15
+ if (result === null)
16
+ return null;
17
+ if (result instanceof Blob)
18
+ return result.arrayBuffer();
19
+ return result;
20
+ }
21
+ async delete(storageId) {
22
+ return this.blobstore.delete(storageId);
23
+ }
24
+ async getUrl(storageId) {
25
+ return this.blobstore.getUrl(storageId);
26
+ }
27
+ }
@@ -0,0 +1,169 @@
1
+ /**
2
+ * Base class for ConcaveDO implementations
3
+ *
4
+ * This provides the common functionality shared between runtime-cf and runtime-cloud.
5
+ * Subclasses provide platform-specific wiring through constructor config.
6
+ */
7
+ import { DurableObject } from "cloudflare:workers";
8
+ import type { UdfExec, UdfResult } from "@concavejs/core/udf";
9
+ import type { DocStore, DocumentLogEntry, DatabaseIndexUpdate, Interval, Order, IndexKeyBytes, LatestDocument, TimestampRange, InternalDocumentId, GlobalKey, DocumentPrevTsQuery, SearchIndexDefinition, VectorIndexDefinition } from "@concavejs/core/docstore";
10
+ import type { BlobStore, StorageOptions, StorageMetadata } from "@concavejs/core/abstractions";
11
+ import { ScheduledFunctionExecutor, CronExecutor } from "@concavejs/core";
12
+ import type { SerializedKeyRange } from "@concavejs/core/queryengine";
13
+ import type { JSONValue } from "convex/values";
14
+ import type { JWTValidationConfig } from "@concavejs/core/auth";
15
+ /**
16
+ * Configuration for ConcaveDOBase
17
+ */
18
+ export interface ConcaveDOAdapterContext<Env = any> {
19
+ state: DurableObjectState;
20
+ env: Env;
21
+ instance: string;
22
+ }
23
+ export interface ConcaveDOExecutorContext<Env = any> extends ConcaveDOAdapterContext<Env> {
24
+ docstore: DocStore;
25
+ blobstore?: BlobStore;
26
+ }
27
+ export interface ConcaveDOConfig {
28
+ /** Override the DocStore implementation (default: DODocStore) */
29
+ createDocstore?: (context: ConcaveDOAdapterContext) => DocStore;
30
+ /** Override the BlobStore implementation */
31
+ createBlobstore?: (context: ConcaveDOAdapterContext) => BlobStore | undefined;
32
+ /** Create the UDF executor from resolved runtime services */
33
+ createUdfExecutor: (context: ConcaveDOExecutorContext) => UdfExec;
34
+ /**
35
+ * Pre-computed cron specs to sync on initialization.
36
+ * When provided, these are used directly instead of auto-discovering from modules.
37
+ * Useful for deploy pipelines that extract specs at build time.
38
+ */
39
+ cronSpecs?: Record<string, any>;
40
+ /**
41
+ * Whether to auto-discover cron specs from registered modules (default: true).
42
+ * Set to false to disable auto-discovery (e.g. if no modules are registered globally).
43
+ * Ignored when `cronSpecs` is explicitly provided.
44
+ */
45
+ discoverCrons?: boolean;
46
+ }
47
+ /**
48
+ * Base class for Concave Durable Objects
49
+ *
50
+ * Provides:
51
+ * - Request handling (fetch, syscall, HTTP)
52
+ * - Scheduled function execution
53
+ * - Cron job execution
54
+ * - SyncDO notification
55
+ *
56
+ * Subclasses/configurers provide:
57
+ * - createUdfExecutor(): Platform-specific UDF executor creation
58
+ */
59
+ export declare class ConcaveDOBase extends DurableObject {
60
+ protected _docstore: DocStore;
61
+ protected _blobstore?: BlobStore;
62
+ protected udfExecutor: UdfExec;
63
+ protected doState: DurableObjectState;
64
+ env: any;
65
+ protected scheduler: ScheduledFunctionExecutor;
66
+ protected cronExecutor: CronExecutor;
67
+ private readonly docStoreRpc;
68
+ private readonly blobStoreRpc;
69
+ private readonly syncNotifier;
70
+ private schedulerManager;
71
+ /** Cached search/vector index definitions for reuse (e.g. after reset-test-state) */
72
+ protected cachedSearchIndexes: SearchIndexDefinition[];
73
+ protected cachedVectorIndexes: VectorIndexDefinition[];
74
+ /** Cached JWT providers from auth.config.ts */
75
+ protected cachedJwtProviders: JWTValidationConfig[];
76
+ constructor(state: DurableObjectState, env: any, config: ConcaveDOConfig);
77
+ /**
78
+ * Initialize scheduler and cron executor
79
+ */
80
+ private initializeSchedulers;
81
+ /**
82
+ * Discover and sync cron specs during DO initialization.
83
+ * Supports both pre-computed specs (from deploy pipelines) and
84
+ * runtime auto-discovery from the global module registry.
85
+ */
86
+ private initializeCronSpecs;
87
+ private currentSnapshotTimestamp;
88
+ /**
89
+ * Main request handler
90
+ */
91
+ fetch(request: Request): Promise<Response>;
92
+ /**
93
+ * Handle UDF execution request
94
+ */
95
+ protected handleUdfRequest(request: Request): Promise<Response>;
96
+ /**
97
+ * Handle HTTP action requests
98
+ */
99
+ protected handleHttp(request: Request): Promise<Response>;
100
+ /**
101
+ * Execute a UDF
102
+ */
103
+ protected execute(path: string, args: Record<string, any>, type: "query" | "mutation" | "action", auth?: any, componentPath?: string, requestId?: string, snapshotTimestamp?: bigint): Promise<UdfResult>;
104
+ /**
105
+ * Handle scheduled function alarms
106
+ */
107
+ alarm(): Promise<void>;
108
+ /**
109
+ * Reschedule alarms
110
+ */
111
+ protected reschedule(): Promise<void>;
112
+ /**
113
+ * Sync cron specs
114
+ */
115
+ syncCronSpecs(cronSpecs: Record<string, any>): Promise<void>;
116
+ setupSchema(options?: {
117
+ searchIndexes?: SearchIndexDefinition[];
118
+ vectorIndexes?: VectorIndexDefinition[];
119
+ }): Promise<void>;
120
+ write(documents: DocumentLogEntry[], indexes: Set<{
121
+ ts: bigint;
122
+ update: DatabaseIndexUpdate;
123
+ }>, conflictStrategy: "Error" | "Overwrite"): Promise<void>;
124
+ get(id: InternalDocumentId, readTimestamp?: bigint): Promise<LatestDocument | null>;
125
+ scan(table: string, readTimestamp?: bigint): Promise<LatestDocument[]>;
126
+ scanPaginated(table: string, cursor: string | null, limit: number, order: Order, readTimestamp?: bigint): Promise<{
127
+ documents: LatestDocument[];
128
+ nextCursor: string | null;
129
+ hasMore: boolean;
130
+ }>;
131
+ /**
132
+ * Generators return arrays over RPC (cannot stream async generators)
133
+ */
134
+ index_scan(indexId: string, tabletId: string, readTimestamp: bigint, interval: Interval, order: Order): Promise<[IndexKeyBytes, LatestDocument][]>;
135
+ /**
136
+ * Generators return arrays over RPC (cannot stream async generators)
137
+ */
138
+ load_documents(range: TimestampRange, order: Order): Promise<DocumentLogEntry[]>;
139
+ count(table: string): Promise<number>;
140
+ search(indexId: string, searchQuery: string, filters: Map<string, unknown>, options?: {
141
+ limit?: number;
142
+ }): Promise<{
143
+ doc: LatestDocument;
144
+ score: number;
145
+ }[]>;
146
+ vectorSearch(indexId: string, vector: number[], limit: number, filters: Map<string, string>): Promise<{
147
+ doc: LatestDocument;
148
+ score: number;
149
+ }[]>;
150
+ getGlobal(key: GlobalKey): Promise<JSONValue | null>;
151
+ writeGlobal(key: GlobalKey, value: JSONValue): Promise<void>;
152
+ previous_revisions(queries: Set<{
153
+ id: InternalDocumentId;
154
+ ts: bigint;
155
+ }>): Promise<[string, DocumentLogEntry][]>;
156
+ previous_revisions_of_documents(queries: Set<DocumentPrevTsQuery>): Promise<[string, DocumentLogEntry][]>;
157
+ blobstoreStore(buffer: ArrayBuffer, options?: StorageOptions): Promise<StorageMetadata>;
158
+ blobstoreGet(storageId: string): Promise<ArrayBuffer | null>;
159
+ blobstoreDelete(storageId: string): Promise<void>;
160
+ blobstoreGetUrl(storageId: string): Promise<string | null>;
161
+ /**
162
+ * Notify SyncDO of writes for subscription invalidation
163
+ */
164
+ protected notifySyncDo(writtenRanges?: SerializedKeyRange[], writtenTables?: string[] | undefined, commitTimestamp?: bigint): Promise<void>;
165
+ /**
166
+ * Get CORS headers for responses
167
+ */
168
+ protected corsHeaders(request?: Request): Record<string, string>;
169
+ }