@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.
- package/dist/adapters/cf-websocket-adapter.d.ts +38 -0
- package/dist/adapters/cf-websocket-adapter.js +83 -0
- package/dist/durable-objects/blobstore-rpc.d.ts +13 -0
- package/dist/durable-objects/blobstore-rpc.js +27 -0
- package/dist/durable-objects/concave-do-base.d.ts +169 -0
- package/dist/durable-objects/concave-do-base.js +466 -0
- package/dist/durable-objects/docstore-rpc.d.ts +46 -0
- package/dist/durable-objects/docstore-rpc.js +63 -0
- package/dist/durable-objects/scheduler-manager.d.ts +19 -0
- package/dist/durable-objects/scheduler-manager.js +53 -0
- package/dist/durable-objects/sync-notifier.d.ts +16 -0
- package/dist/durable-objects/sync-notifier.js +38 -0
- package/dist/env.d.ts +19 -0
- package/dist/env.js +6 -0
- package/dist/http/dx-http.d.ts +43 -0
- package/dist/http/dx-http.js +327 -0
- package/dist/http/http-api.d.ts +38 -0
- package/dist/http/http-api.js +399 -0
- package/dist/http/index.d.ts +7 -0
- package/dist/http/index.js +7 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +27 -0
- package/dist/internal.d.ts +4 -0
- package/dist/internal.js +4 -0
- package/dist/routing/instance.d.ts +25 -0
- package/dist/routing/instance.js +101 -0
- package/dist/routing/sync-topology.d.ts +40 -0
- package/dist/routing/sync-topology.js +669 -0
- package/dist/rpc/blobstore-proxy.d.ts +11 -0
- package/dist/rpc/blobstore-proxy.js +28 -0
- package/dist/rpc/docstore-proxy.d.ts +11 -0
- package/dist/rpc/docstore-proxy.js +73 -0
- package/dist/rpc/index.d.ts +2 -0
- package/dist/rpc/index.js +2 -0
- package/dist/sync/cf-websocket-adapter.d.ts +15 -0
- package/dist/sync/cf-websocket-adapter.js +22 -0
- package/dist/sync/concave-do-udf-executor.d.ts +46 -0
- package/dist/sync/concave-do-udf-executor.js +75 -0
- package/dist/sync/index.d.ts +2 -0
- package/dist/sync/index.js +2 -0
- package/dist/udf/executor/do-client-executor.d.ts +14 -0
- package/dist/udf/executor/do-client-executor.js +58 -0
- package/dist/udf/executor/index.d.ts +8 -0
- package/dist/udf/executor/index.js +8 -0
- package/dist/udf/executor/inline-executor.d.ts +13 -0
- package/dist/udf/executor/inline-executor.js +25 -0
- package/dist/udf/executor/isolated-executor.d.ts +24 -0
- package/dist/udf/executor/isolated-executor.js +31 -0
- package/dist/udf/executor/shim-content.d.ts +1 -0
- package/dist/udf/executor/shim-content.js +3 -0
- package/dist/worker/create-concave-worker.d.ts +79 -0
- package/dist/worker/create-concave-worker.js +196 -0
- package/dist/worker/index.d.ts +6 -0
- package/dist/worker/index.js +6 -0
- package/dist/worker/udf-worker.d.ts +25 -0
- package/dist/worker/udf-worker.js +63 -0
- 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
|
+
}
|