orez 0.5.20 → 0.5.22
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/cf-do/application-sql.d.ts +49 -0
- package/dist/cf-do/application-sql.d.ts.map +1 -0
- package/dist/cf-do/application-sql.js +37 -0
- package/dist/cf-do/application-sql.js.map +1 -0
- package/dist/cf-do/worker.d.ts +28 -2
- package/dist/cf-do/worker.d.ts.map +1 -1
- package/dist/cf-do/worker.js +146 -13
- package/dist/cf-do/worker.js.map +1 -1
- package/dist/pg-sqlite-compiler/compiler.d.ts.map +1 -1
- package/dist/pg-sqlite-compiler/compiler.js +9 -3
- package/dist/pg-sqlite-compiler/compiler.js.map +1 -1
- package/dist/pg-sqlite-compiler/passes/array.d.ts +3 -0
- package/dist/pg-sqlite-compiler/passes/array.d.ts.map +1 -0
- package/dist/pg-sqlite-compiler/passes/array.js +223 -0
- package/dist/pg-sqlite-compiler/passes/array.js.map +1 -0
- package/dist/pg-sqlite-compiler/passes/index.d.ts +3 -0
- package/dist/pg-sqlite-compiler/passes/index.d.ts.map +1 -1
- package/dist/pg-sqlite-compiler/passes/index.js +2 -1
- package/dist/pg-sqlite-compiler/passes/index.js.map +1 -1
- package/dist/pg-sqlite-compiler/types.d.ts +9 -0
- package/dist/pg-sqlite-compiler/types.d.ts.map +1 -1
- package/dist/sync-browser-host/host.d.ts.map +1 -1
- package/dist/sync-browser-host/host.js +4 -3
- package/dist/sync-browser-host/host.js.map +1 -1
- package/dist/sync-browser-host/message-port.d.ts.map +1 -1
- package/dist/sync-browser-host/message-port.js +10 -4
- package/dist/sync-browser-host/message-port.js.map +1 -1
- package/dist/sync-browser-host/sqlite-adapter.d.ts +3 -2
- package/dist/sync-browser-host/sqlite-adapter.d.ts.map +1 -1
- package/dist/sync-browser-host/sqlite-adapter.js +12 -5
- package/dist/sync-browser-host/sqlite-adapter.js.map +1 -1
- package/dist/sync-browser-host/types.d.ts +5 -4
- package/dist/sync-browser-host/types.d.ts.map +1 -1
- package/dist/sync-browser-host/types.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { SQLiteExecResult, SqlStatementMetadata } from 'orez-sync-cf-host';
|
|
2
|
+
import type { DeferredEffect } from 'orez-sync-cf-host/post-commit';
|
|
3
|
+
import type { CompiledTransactionQueryPlan, TransactionQueryBudget, TransactionQueryFormat } from 'orez-sync-cf-host/transaction-query';
|
|
4
|
+
export type ApplicationSqlQueryCompiler = (ast: unknown, format: TransactionQueryFormat) => CompiledTransactionQueryPlan | Promise<CompiledTransactionQueryPlan>;
|
|
5
|
+
export type ApplicationSqlTable = Pick<SqlStatementMetadata, 'table' | 'publicTable'> & {
|
|
6
|
+
/** capture rollback images without publishing this table to Zero clients */
|
|
7
|
+
publish?: boolean;
|
|
8
|
+
};
|
|
9
|
+
export type ApplicationSqlExecResult = SQLiteExecResult;
|
|
10
|
+
export type ApplicationSqlTransaction = {
|
|
11
|
+
exec(sql: string, params?: readonly unknown[], metadata?: SqlStatementMetadata): Promise<ApplicationSqlExecResult>;
|
|
12
|
+
query<Row extends Record<string, unknown> = Record<string, unknown>>(sql: string, params?: readonly unknown[]): Promise<Row[]>;
|
|
13
|
+
queryAst<Result = unknown>(ast: unknown, format: TransactionQueryFormat, queryName?: string): Promise<Result>;
|
|
14
|
+
registerTables(tables: readonly ApplicationSqlTable[]): Promise<void>;
|
|
15
|
+
};
|
|
16
|
+
export type ApplicationSqlTransactionContext = {
|
|
17
|
+
defer(effect: DeferredEffect): void;
|
|
18
|
+
};
|
|
19
|
+
export type ApplicationSqlTransactionWork<Value> = (tx: ApplicationSqlTransaction, context: ApplicationSqlTransactionContext) => Value | Promise<Value>;
|
|
20
|
+
/**
|
|
21
|
+
* Private Durable Object RPC protocol. Transaction callbacks stay in the
|
|
22
|
+
* caller: every SQL turn is tagged with a serialized session id, avoiding a
|
|
23
|
+
* re-entrant RPC call into a Durable Object that is awaiting a callback.
|
|
24
|
+
*/
|
|
25
|
+
export type ApplicationSqlRpc = {
|
|
26
|
+
applicationSqlQuery<Row extends Record<string, unknown> = Record<string, unknown>>(sql: string, params?: readonly unknown[]): Promise<Row[]>;
|
|
27
|
+
applicationSqlExec(sql: string, params?: readonly unknown[], metadata?: SqlStatementMetadata): Promise<ApplicationSqlExecResult>;
|
|
28
|
+
applicationSqlRegisterTables(tables: readonly ApplicationSqlTable[]): Promise<void>;
|
|
29
|
+
applicationSqlBegin(sessionID: string): Promise<void>;
|
|
30
|
+
applicationSqlSessionQuery<Row extends Record<string, unknown> = Record<string, unknown>>(sessionID: string, sql: string, params?: readonly unknown[]): Promise<Row[]>;
|
|
31
|
+
applicationSqlSessionExec(sessionID: string, sql: string, params?: readonly unknown[], metadata?: SqlStatementMetadata): Promise<ApplicationSqlExecResult>;
|
|
32
|
+
applicationSqlSessionQueryPlan<Result = unknown>(sessionID: string, plan: CompiledTransactionQueryPlan, queryName?: string, queryBudget?: Partial<TransactionQueryBudget>): Promise<Result>;
|
|
33
|
+
applicationSqlSessionRegisterTables(sessionID: string, tables: readonly ApplicationSqlTable[]): Promise<void>;
|
|
34
|
+
applicationSqlCommit(sessionID: string): Promise<void>;
|
|
35
|
+
applicationSqlRollback(sessionID: string): Promise<void>;
|
|
36
|
+
};
|
|
37
|
+
export type ApplicationSqlDurableObjectNamespace = {
|
|
38
|
+
idFromName(name: string): unknown;
|
|
39
|
+
get(id: unknown): ApplicationSqlRpc;
|
|
40
|
+
};
|
|
41
|
+
export type ApplicationSqlClient = {
|
|
42
|
+
readonly namespace: string;
|
|
43
|
+
query<Row extends Record<string, unknown> = Record<string, unknown>>(sql: string, params?: readonly unknown[]): Promise<Row[]>;
|
|
44
|
+
exec(sql: string, params?: readonly unknown[], metadata?: SqlStatementMetadata): Promise<ApplicationSqlExecResult>;
|
|
45
|
+
registerTables(tables: readonly ApplicationSqlTable[]): Promise<void>;
|
|
46
|
+
transaction<Value>(compileQuery: ApplicationSqlQueryCompiler, work: ApplicationSqlTransactionWork<Value>, queryBudget?: Partial<TransactionQueryBudget>): Promise<Value>;
|
|
47
|
+
};
|
|
48
|
+
export declare function createApplicationSqlClient(durableObjects: ApplicationSqlDurableObjectNamespace, namespace: string): ApplicationSqlClient;
|
|
49
|
+
//# sourceMappingURL=application-sql.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"application-sql.d.ts","sourceRoot":"","sources":["../../src/cf-do/application-sql.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export function createApplicationSqlClient(durableObjects, namespace) {
|
|
2
|
+
if (!namespace)
|
|
3
|
+
throw new TypeError('application SQLite namespace is required');
|
|
4
|
+
const target = durableObjects.get(durableObjects.idFromName(namespace));
|
|
5
|
+
return {
|
|
6
|
+
namespace,
|
|
7
|
+
query: (sql, params = []) => target.applicationSqlQuery(sql, params),
|
|
8
|
+
exec: (sql, params = [], metadata) => target.applicationSqlExec(sql, params, metadata),
|
|
9
|
+
registerTables: (tables) => target.applicationSqlRegisterTables(tables),
|
|
10
|
+
async transaction(compileQuery, work, queryBudget) {
|
|
11
|
+
const sessionID = crypto.randomUUID();
|
|
12
|
+
const effects = [];
|
|
13
|
+
await target.applicationSqlBegin(sessionID);
|
|
14
|
+
const tx = {
|
|
15
|
+
exec: (sql, params = [], metadata) => target.applicationSqlSessionExec(sessionID, sql, params, metadata),
|
|
16
|
+
query: (sql, params = []) => target.applicationSqlSessionQuery(sessionID, sql, params),
|
|
17
|
+
async queryAst(ast, format, queryName) {
|
|
18
|
+
const plan = await compileQuery(ast, format);
|
|
19
|
+
return target.applicationSqlSessionQueryPlan(sessionID, plan, queryName, queryBudget);
|
|
20
|
+
},
|
|
21
|
+
registerTables: (tables) => target.applicationSqlSessionRegisterTables(sessionID, tables),
|
|
22
|
+
};
|
|
23
|
+
try {
|
|
24
|
+
const value = await work(tx, { defer: (effect) => effects.push(effect) });
|
|
25
|
+
await target.applicationSqlCommit(sessionID);
|
|
26
|
+
for (const effect of effects)
|
|
27
|
+
await effect();
|
|
28
|
+
return value;
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
await target.applicationSqlRollback(sessionID).catch(() => { });
|
|
32
|
+
throw error;
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=application-sql.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"application-sql.js","sourceRoot":"","sources":["../../src/cf-do/application-sql.ts"],"names":[],"mappings":"AAmHA,MAAM,UAAU,0BAA0B,CACxC,cAAoD,EACpD,SAAiB;IAEjB,IAAI,CAAC,SAAS;QAAE,MAAM,IAAI,SAAS,CAAC,0CAA0C,CAAC,CAAA;IAC/E,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,cAAc,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAA;IACvE,OAAO;QACL,SAAS;QACT,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,GAAG,EAAE,MAAM,CAAC;QACpE,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,EAAE,EAAE,QAAQ,EAAE,EAAE,CACnC,MAAM,CAAC,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC;QAClD,cAAc,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,4BAA4B,CAAC,MAAM,CAAC;QACvE,KAAK,CAAC,WAAW,CAAC,YAAY,EAAE,IAAI,EAAE,WAAW;YAC/C,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,EAAE,CAAA;YACrC,MAAM,OAAO,GAAqB,EAAE,CAAA;YACpC,MAAM,MAAM,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAA;YAC3C,MAAM,EAAE,GAA8B;gBACpC,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,EAAE,EAAE,QAAQ,EAAE,EAAE,CACnC,MAAM,CAAC,yBAAyB,CAAC,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC;gBACpE,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,EAAE,EAAE,EAAE,CAC1B,MAAM,CAAC,0BAA0B,CAAC,SAAS,EAAE,GAAG,EAAE,MAAM,CAAC;gBAC3D,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS;oBACnC,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;oBAC5C,OAAO,MAAM,CAAC,8BAA8B,CAC1C,SAAS,EACT,IAAI,EACJ,SAAS,EACT,WAAW,CACZ,CAAA;gBACH,CAAC;gBACD,cAAc,EAAE,CAAC,MAAM,EAAE,EAAE,CACzB,MAAM,CAAC,mCAAmC,CAAC,SAAS,EAAE,MAAM,CAAC;aAChE,CAAA;YACD,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;gBACzE,MAAM,MAAM,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAA;gBAC5C,KAAK,MAAM,MAAM,IAAI,OAAO;oBAAE,MAAM,MAAM,EAAE,CAAA;gBAC5C,OAAO,KAAK,CAAA;YACd,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,MAAM,CAAC,sBAAsB,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;gBAC9D,MAAM,KAAK,CAAA;YACb,CAAC;QACH,CAAC;KACF,CAAA;AACH,CAAC"}
|
package/dist/cf-do/worker.d.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { DurableObject } from 'cloudflare:workers';
|
|
2
2
|
import { type DeferredEffect } from 'orez-sync-cf-host/post-commit';
|
|
3
3
|
import { type CompiledTransactionQueryPlan, type TransactionQueryBudget, type TransactionQueryFormat } from 'orez-sync-cf-host/transaction-query';
|
|
4
|
+
import type { ApplicationSqlExecResult, ApplicationSqlTable } from './application-sql.js';
|
|
5
|
+
import type { SqlStatementMetadata } from 'orez-sync-cf-host';
|
|
6
|
+
export { createApplicationSqlClient } from './application-sql.js';
|
|
7
|
+
export type { ApplicationSqlClient, ApplicationSqlDurableObjectNamespace, ApplicationSqlExecResult, ApplicationSqlQueryCompiler, ApplicationSqlRpc, ApplicationSqlTable, ApplicationSqlTransaction, ApplicationSqlTransactionContext, ApplicationSqlTransactionWork, } from './application-sql.js';
|
|
8
|
+
export type { SqlStatementMetadata } from 'orez-sync-cf-host';
|
|
4
9
|
/**
|
|
5
10
|
* zero-do: Durable Object that exposes raw SQL execution over ctx.storage.sql.
|
|
6
11
|
*
|
|
@@ -22,9 +27,9 @@ interface Env {
|
|
|
22
27
|
OREZ_DO_WRITE_BUDGET_ADMIN_TOKEN?: string;
|
|
23
28
|
OREZ_DO_WRITE_BUDGET_DISABLED?: string;
|
|
24
29
|
}
|
|
25
|
-
export type ZeroDOQueryCompiler = (ast: unknown, format: TransactionQueryFormat) => CompiledTransactionQueryPlan
|
|
30
|
+
export type ZeroDOQueryCompiler = (ast: unknown, format: TransactionQueryFormat) => CompiledTransactionQueryPlan | Promise<CompiledTransactionQueryPlan>;
|
|
26
31
|
export type ZeroDOTransactionExecutor = {
|
|
27
|
-
exec(sql: string, params?: readonly unknown[]): Promise<
|
|
32
|
+
exec(sql: string, params?: readonly unknown[], metadata?: SqlStatementMetadata): Promise<ApplicationSqlExecResult>;
|
|
28
33
|
query<Row extends Record<string, unknown> = Record<string, unknown>>(sql: string, params?: readonly unknown[]): Promise<Row[]>;
|
|
29
34
|
queryAst<Result = unknown>(ast: unknown, format: TransactionQueryFormat, queryName?: string): Promise<Result>;
|
|
30
35
|
};
|
|
@@ -42,6 +47,7 @@ export declare class ZeroDO extends DurableObject {
|
|
|
42
47
|
private writeBudgetAdminToken;
|
|
43
48
|
private activeWriteMeasurements;
|
|
44
49
|
private pendingChangesSchemaReady;
|
|
50
|
+
private applicationSqlSessionID;
|
|
45
51
|
private recordWriteBudgetRows;
|
|
46
52
|
private writeBudgetErrorResponse;
|
|
47
53
|
constructor(ctx: DurableObjectState, env: Env);
|
|
@@ -102,6 +108,26 @@ export declare class ZeroDO extends DurableObject {
|
|
|
102
108
|
* external effects run only after the storage transaction commits.
|
|
103
109
|
*/
|
|
104
110
|
protected runApplicationTransaction<T>(compileQuery: ZeroDOQueryCompiler, work: (tx: ZeroDOTransactionExecutor, context: ZeroDOTransactionContext) => T | Promise<T>, queryBudget?: Partial<TransactionQueryBudget>): Promise<T>;
|
|
111
|
+
private assertApplicationSqlSession;
|
|
112
|
+
private assertNoApplicationSqlSession;
|
|
113
|
+
private registerApplicationSqlTables;
|
|
114
|
+
/**
|
|
115
|
+
* Private Durable Object RPC surface for the application SQLite client.
|
|
116
|
+
*
|
|
117
|
+
* The client owns its callback and sends serialized session turns. This
|
|
118
|
+
* avoids re-entering a Durable Object while it waits on a callback. These
|
|
119
|
+
* methods are intentionally absent from fetch().
|
|
120
|
+
*/
|
|
121
|
+
applicationSqlQuery<Row extends Record<string, unknown> = Record<string, unknown>>(sql: string, params?: readonly unknown[]): Promise<Row[]>;
|
|
122
|
+
applicationSqlExec(sql: string, params?: readonly unknown[], metadata?: SqlStatementMetadata): Promise<ApplicationSqlExecResult>;
|
|
123
|
+
applicationSqlRegisterTables(tables: readonly ApplicationSqlTable[]): Promise<void>;
|
|
124
|
+
applicationSqlBegin(sessionID: string): Promise<void>;
|
|
125
|
+
applicationSqlSessionQuery<Row extends Record<string, unknown> = Record<string, unknown>>(sessionID: string, sql: string, params?: readonly unknown[]): Promise<Row[]>;
|
|
126
|
+
applicationSqlSessionExec(sessionID: string, sql: string, params?: readonly unknown[], metadata?: SqlStatementMetadata): Promise<ApplicationSqlExecResult>;
|
|
127
|
+
applicationSqlSessionQueryPlan<Result = unknown>(sessionID: string, plan: CompiledTransactionQueryPlan, queryName?: string, queryBudget?: Partial<TransactionQueryBudget>): Promise<Result>;
|
|
128
|
+
applicationSqlSessionRegisterTables(sessionID: string, tables: readonly ApplicationSqlTable[]): Promise<void>;
|
|
129
|
+
applicationSqlCommit(sessionID: string): Promise<void>;
|
|
130
|
+
applicationSqlRollback(sessionID: string): Promise<void>;
|
|
105
131
|
private atomicallySync;
|
|
106
132
|
private invalidateSchemaCaches;
|
|
107
133
|
private tableHasColumn;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../src/cf-do/worker.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAEL,KAAK,cAAc,EACpB,MAAM,+BAA+B,CAAA;AACtC,OAAO,EAEL,KAAK,4BAA4B,EACjC,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,EAC5B,MAAM,qCAAqC,CAAA;AA+B5C;;;;;;;;;;;;;GAaG;AAEH,UAAU,GAAG;IACX,OAAO,EAAE,sBAAsB,CAAA;IAC/B,yBAAyB,CAAC,EAAE,MAAM,CAAA;IAClC,8BAA8B,CAAC,EAAE,MAAM,CAAA;IACvC,gCAAgC,CAAC,EAAE,MAAM,CAAA;IACzC,6BAA6B,CAAC,EAAE,MAAM,CAAA;CACvC;AA+DD,MAAM,MAAM,mBAAmB,GAAG,CAChC,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,sBAAsB,KAC3B,4BAA4B,CAAA;
|
|
1
|
+
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../src/cf-do/worker.ts"],"names":[],"mappings":"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"}
|
package/dist/cf-do/worker.js
CHANGED
|
@@ -7,6 +7,7 @@ import { TransactionalCdc, } from './cdc.js';
|
|
|
7
7
|
import { appendPendingChange, deletePendingChanges, ensurePendingChangesTable, rollbackPendingChanges, } from './row-undo.js';
|
|
8
8
|
import { commitTxJournal, recoverTxJournal, rollbackTxJournal, snapshotSideEffectWriteTables, snapshotTxSchema, upgradeToTableSnapshot, } from './tx-journal.js';
|
|
9
9
|
import { DurableWatermarkState } from './watermark.js';
|
|
10
|
+
export { createApplicationSqlClient } from './application-sql.js';
|
|
10
11
|
const SCHEMA_VERSION = 1;
|
|
11
12
|
const SQL_ERROR_SNIPPET_RADIUS = 1600;
|
|
12
13
|
const SQL_ERROR_FALLBACK_LIMIT = 4000;
|
|
@@ -70,6 +71,21 @@ function assertApplicationTransactionSQL(sql) {
|
|
|
70
71
|
throw new TypeError('transaction SQL is owned by ZeroDO');
|
|
71
72
|
}
|
|
72
73
|
}
|
|
74
|
+
function applicationSqlTrack(metadata) {
|
|
75
|
+
if (!metadata)
|
|
76
|
+
return undefined;
|
|
77
|
+
const operations = {
|
|
78
|
+
insert: 'INSERT',
|
|
79
|
+
update: 'UPDATE',
|
|
80
|
+
delete: 'DELETE',
|
|
81
|
+
upsert: 'UPSERT',
|
|
82
|
+
};
|
|
83
|
+
return {
|
|
84
|
+
tableName: metadata.publicTable,
|
|
85
|
+
physicalTableName: metadata.table,
|
|
86
|
+
operation: operations[metadata.kind],
|
|
87
|
+
};
|
|
88
|
+
}
|
|
73
89
|
export class ZeroDO extends DurableObject {
|
|
74
90
|
sql;
|
|
75
91
|
watermarks;
|
|
@@ -81,6 +97,7 @@ export class ZeroDO extends DurableObject {
|
|
|
81
97
|
writeBudgetAdminToken;
|
|
82
98
|
activeWriteMeasurements = null;
|
|
83
99
|
pendingChangesSchemaReady = false;
|
|
100
|
+
applicationSqlSessionID = null;
|
|
84
101
|
recordWriteBudgetRows(rows) {
|
|
85
102
|
const wasTripped = this.writeBudget.status().tripped;
|
|
86
103
|
try {
|
|
@@ -151,15 +168,25 @@ export class ZeroDO extends DurableObject {
|
|
|
151
168
|
this.recordWriteBudgetRows(rows);
|
|
152
169
|
});
|
|
153
170
|
};
|
|
154
|
-
|
|
155
|
-
|
|
171
|
+
this.cdc = new TransactionalCdc(this.sql);
|
|
172
|
+
this.watermarks = new DurableWatermarkState(this.sql);
|
|
173
|
+
ctx.blockConcurrencyWhile(async () => {
|
|
174
|
+
if (!this.writeBudgetDisabled) {
|
|
156
175
|
const trippedAt = await ctx.storage.get(WRITE_BUDGET_TRIPPED_KEY);
|
|
157
176
|
if (trippedAt)
|
|
158
177
|
this.writeBudget.restoreTrip(trippedAt);
|
|
178
|
+
}
|
|
179
|
+
const recovered = await this.atomically(() => {
|
|
180
|
+
const transactionIDs = recoverTxJournal(this.sql, 'application', (transactionID) => {
|
|
181
|
+
this.rollbackPendingTrackedChanges(transactionID);
|
|
182
|
+
});
|
|
183
|
+
for (const transactionID of transactionIDs)
|
|
184
|
+
this.deletePendingTrackedChanges(transactionID);
|
|
185
|
+
return transactionIDs;
|
|
159
186
|
});
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
187
|
+
if (recovered.length)
|
|
188
|
+
this.invalidateSchemaCaches();
|
|
189
|
+
});
|
|
163
190
|
}
|
|
164
191
|
async fetch(request) {
|
|
165
192
|
const url = new URL(request.url);
|
|
@@ -811,19 +838,20 @@ export class ZeroDO extends DurableObject {
|
|
|
811
838
|
*/
|
|
812
839
|
async runApplicationTransaction(compileQuery, work, queryBudget) {
|
|
813
840
|
const effects = createPostCommitEffects();
|
|
814
|
-
const execute = (sql, params = []) => {
|
|
841
|
+
const execute = (sql, params = [], metadata) => {
|
|
815
842
|
assertApplicationTransactionSQL(sql);
|
|
816
|
-
return this.executeSQL(sql, [...params]);
|
|
843
|
+
return this.executeSQL(sql, [...params], applicationSqlTrack(metadata));
|
|
817
844
|
};
|
|
818
845
|
const tx = {
|
|
819
|
-
async exec(sql, params = []) {
|
|
820
|
-
execute(sql, params);
|
|
846
|
+
async exec(sql, params = [], metadata) {
|
|
847
|
+
const result = execute(sql, params, metadata);
|
|
848
|
+
return { changes: result.changes };
|
|
821
849
|
},
|
|
822
850
|
async query(sql, params = []) {
|
|
823
851
|
return execute(sql, params).rows;
|
|
824
852
|
},
|
|
825
853
|
async queryAst(ast, format, queryName) {
|
|
826
|
-
const compiled = compileQuery(ast, format);
|
|
854
|
+
const compiled = await compileQuery(ast, format);
|
|
827
855
|
return executeTransactionQueryPlan(compiled, (sql, params) => execute(sql, params).rows, { queryName, budget: queryBudget });
|
|
828
856
|
},
|
|
829
857
|
};
|
|
@@ -839,6 +867,100 @@ export class ZeroDO extends DurableObject {
|
|
|
839
867
|
});
|
|
840
868
|
return value;
|
|
841
869
|
}
|
|
870
|
+
assertApplicationSqlSession(sessionID) {
|
|
871
|
+
if (!sessionID || this.applicationSqlSessionID !== sessionID) {
|
|
872
|
+
throw new Error('application SQLite session is not active');
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
assertNoApplicationSqlSession() {
|
|
876
|
+
if (this.applicationSqlSessionID) {
|
|
877
|
+
throw new Error('application SQLite session is active');
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
registerApplicationSqlTables(tables) {
|
|
881
|
+
for (const table of tables) {
|
|
882
|
+
this.cdc.ensureTable({
|
|
883
|
+
physicalTableName: table.table,
|
|
884
|
+
tableName: table.publicTable,
|
|
885
|
+
...(table.publish === false ? { publish: false } : null),
|
|
886
|
+
});
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
/**
|
|
890
|
+
* Private Durable Object RPC surface for the application SQLite client.
|
|
891
|
+
*
|
|
892
|
+
* The client owns its callback and sends serialized session turns. This
|
|
893
|
+
* avoids re-entering a Durable Object while it waits on a callback. These
|
|
894
|
+
* methods are intentionally absent from fetch().
|
|
895
|
+
*/
|
|
896
|
+
async applicationSqlQuery(sql, params = []) {
|
|
897
|
+
this.assertNoApplicationSqlSession();
|
|
898
|
+
return this.runApplicationTransaction(() => {
|
|
899
|
+
throw new Error('queryAst requires an application SQLite transaction compiler');
|
|
900
|
+
}, (tx) => tx.query(sql, params));
|
|
901
|
+
}
|
|
902
|
+
async applicationSqlExec(sql, params = [], metadata) {
|
|
903
|
+
this.assertNoApplicationSqlSession();
|
|
904
|
+
return this.runApplicationTransaction(() => {
|
|
905
|
+
throw new Error('queryAst requires an application SQLite transaction compiler');
|
|
906
|
+
}, (tx) => tx.exec(sql, params, metadata));
|
|
907
|
+
}
|
|
908
|
+
async applicationSqlRegisterTables(tables) {
|
|
909
|
+
this.assertNoApplicationSqlSession();
|
|
910
|
+
await this.atomically(() => this.registerApplicationSqlTables(tables));
|
|
911
|
+
}
|
|
912
|
+
async applicationSqlBegin(sessionID) {
|
|
913
|
+
this.assertNoApplicationSqlSession();
|
|
914
|
+
if (!sessionID)
|
|
915
|
+
throw new TypeError('application SQLite session id is required');
|
|
916
|
+
await this.atomically(() => snapshotTxSchema(this.sql, sessionID, 'application'));
|
|
917
|
+
this.applicationSqlSessionID = sessionID;
|
|
918
|
+
}
|
|
919
|
+
async applicationSqlSessionQuery(sessionID, sql, params = []) {
|
|
920
|
+
this.assertApplicationSqlSession(sessionID);
|
|
921
|
+
return this.atomically(() => this.executeSQL(sql, [...params], undefined, sessionID).rows);
|
|
922
|
+
}
|
|
923
|
+
async applicationSqlSessionExec(sessionID, sql, params = [], metadata) {
|
|
924
|
+
this.assertApplicationSqlSession(sessionID);
|
|
925
|
+
return this.atomically(() => {
|
|
926
|
+
const result = this.executeSQL(sql, [...params], applicationSqlTrack(metadata), sessionID);
|
|
927
|
+
return { changes: result.changes };
|
|
928
|
+
});
|
|
929
|
+
}
|
|
930
|
+
async applicationSqlSessionQueryPlan(sessionID, plan, queryName, queryBudget) {
|
|
931
|
+
this.assertApplicationSqlSession(sessionID);
|
|
932
|
+
return this.atomically(() => executeTransactionQueryPlan(plan, (sql, params) => this.executeSQL(sql, params, undefined, sessionID).rows, { queryName, budget: queryBudget }));
|
|
933
|
+
}
|
|
934
|
+
async applicationSqlSessionRegisterTables(sessionID, tables) {
|
|
935
|
+
this.assertApplicationSqlSession(sessionID);
|
|
936
|
+
await this.atomically(() => this.registerApplicationSqlTables(tables));
|
|
937
|
+
}
|
|
938
|
+
async applicationSqlCommit(sessionID) {
|
|
939
|
+
this.assertApplicationSqlSession(sessionID);
|
|
940
|
+
try {
|
|
941
|
+
await this.atomically(() => {
|
|
942
|
+
this.commitPendingTrackedChanges(sessionID);
|
|
943
|
+
commitTxJournal(this.sql, sessionID);
|
|
944
|
+
});
|
|
945
|
+
}
|
|
946
|
+
finally {
|
|
947
|
+
this.applicationSqlSessionID = null;
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
async applicationSqlRollback(sessionID) {
|
|
951
|
+
this.assertApplicationSqlSession(sessionID);
|
|
952
|
+
try {
|
|
953
|
+
await this.atomically(() => {
|
|
954
|
+
this.rollbackPendingTrackedChanges(sessionID);
|
|
955
|
+
rollbackTxJournal(this.sql, sessionID);
|
|
956
|
+
this.deletePendingTrackedChanges(sessionID);
|
|
957
|
+
});
|
|
958
|
+
this.invalidateSchemaCaches();
|
|
959
|
+
}
|
|
960
|
+
finally {
|
|
961
|
+
this.applicationSqlSessionID = null;
|
|
962
|
+
}
|
|
963
|
+
}
|
|
842
964
|
atomicallySync(work) {
|
|
843
965
|
try {
|
|
844
966
|
return this.ctx.storage.transactionSync(work);
|
|
@@ -881,6 +1003,12 @@ export class ZeroDO extends DurableObject {
|
|
|
881
1003
|
else if (track) {
|
|
882
1004
|
capturesTrackedTable = this.cdc.capturesTable(track.tableName);
|
|
883
1005
|
}
|
|
1006
|
+
// SQLite decides whether an INSERT ... ON CONFLICT write inserted or
|
|
1007
|
+
// updated. Only the installed trigger sees that result. Falling back to a
|
|
1008
|
+
// caller-declared operation would publish a false change shape.
|
|
1009
|
+
if (track?.operation === 'UPSERT' && !capturesTrackedTable) {
|
|
1010
|
+
throw new Error(`upsert requires CDC registration for ${track.tableName}`);
|
|
1011
|
+
}
|
|
884
1012
|
// DoBackend already marked this table row-journaled, betting the DO could
|
|
885
1013
|
// capture before/after images for it. When it cannot, that marker promises
|
|
886
1014
|
// a rollback nothing can perform, so take the table snapshot the journal
|
|
@@ -913,12 +1041,16 @@ export class ZeroDO extends DurableObject {
|
|
|
913
1041
|
this.cdc.finishSchemaChange(suspendedCdc);
|
|
914
1042
|
const columns = Array.isArray(cursor.columnNames) ? cursor.columnNames : [];
|
|
915
1043
|
const rows = this.cursorRows(cursor, columns);
|
|
1044
|
+
const rowMutation = isSqlRowMutation(sql);
|
|
1045
|
+
const changes = rowMutation
|
|
1046
|
+
? Number(this.sql.exec('SELECT changes() AS changes').one()?.changes ?? 0)
|
|
1047
|
+
: 0;
|
|
916
1048
|
const mutation = isSqlMutation(sql);
|
|
917
1049
|
if (mutation)
|
|
918
1050
|
this.writeBudget.recordLogical(rows.length);
|
|
919
|
-
if (mutation && !
|
|
1051
|
+
if (mutation && !rowMutation)
|
|
920
1052
|
this.cdc.invalidateSchema();
|
|
921
|
-
const captured = track || (this.cdc.active &&
|
|
1053
|
+
const captured = track || (this.cdc.active && rowMutation) ? this.cdc.drain() : [];
|
|
922
1054
|
for (const change of captured) {
|
|
923
1055
|
this.appendCapturedChange(change, transactionID || track?.transactionID, !snapshotsOwnStatement);
|
|
924
1056
|
}
|
|
@@ -952,10 +1084,11 @@ export class ZeroDO extends DurableObject {
|
|
|
952
1084
|
}
|
|
953
1085
|
const publishedCaptured = captured.filter((change) => change.publish !== false).length;
|
|
954
1086
|
if (!track)
|
|
955
|
-
return { rows, columns, capturedChanges: publishedCaptured };
|
|
1087
|
+
return { rows, columns, changes, capturedChanges: publishedCaptured };
|
|
956
1088
|
return {
|
|
957
1089
|
rows: track.returnRows ? rows : [],
|
|
958
1090
|
columns: track.returnRows ? columns : [],
|
|
1091
|
+
changes,
|
|
959
1092
|
affectedRows: rows.length,
|
|
960
1093
|
capturedChanges: publishedCaptured ||
|
|
961
1094
|
(capturesTrackedTable || track.publish === false ? 0 : rows.length),
|