orez-sync-cf-host 0.16.1 → 0.16.2
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/host.js +1 -1
- package/dist/query-patch.d.ts +17 -4
- package/dist/query-patch.js +36 -15
- package/dist/types.d.ts +13 -0
- package/package.json +3 -3
package/dist/host.js
CHANGED
|
@@ -1293,7 +1293,7 @@ export function createSyncDurableObject(config) {
|
|
|
1293
1293
|
// Zero registry, synchronously: patch application order is
|
|
1294
1294
|
// arrival order by construction, with no cross-request await
|
|
1295
1295
|
// between resolution and the engine transaction.
|
|
1296
|
-
const patch = resolveQueryPatch(queries.patch, config.queries, claims, transformVersion, requestError);
|
|
1296
|
+
const patch = resolveQueryPatch(queries.patch, config.queries, claims, transformVersion, requestError, config.tolerateUnknownQueries === true);
|
|
1297
1297
|
body = { ...body, queries: { ...queries, patch } };
|
|
1298
1298
|
}
|
|
1299
1299
|
body = { ...body, _serverQueryTransformVersion: transformVersion };
|
package/dist/query-patch.d.ts
CHANGED
|
@@ -14,8 +14,21 @@ import type { AnyQueryRegistry } from '@rocicorp/zero';
|
|
|
14
14
|
* `asQueryInternals`, whose instance-tag check fails whenever the app's
|
|
15
15
|
* registry and this host resolve different copies of the zero module.
|
|
16
16
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* one unknown query alongside nine good ones is told
|
|
17
|
+
* By default a name the registry does not contain fails the whole patch (the
|
|
18
|
+
* pull is refused as one unit) and the refusal names the query it came from, so
|
|
19
|
+
* a client that registers one unknown query alongside nine good ones is told
|
|
20
|
+
* which one is unknown. Where client and server ship together that is the right
|
|
21
|
+
* answer: an unknown name means the registry was not regenerated, and a loud
|
|
22
|
+
* failure is how the developer finds out.
|
|
23
|
+
*
|
|
24
|
+
* A host that serves independently shipped clients sets
|
|
25
|
+
* `tolerateUnknownQueries`. A native binary is always older than the server it
|
|
26
|
+
* talks to, so it can ask for a query since renamed or removed; that is version
|
|
27
|
+
* skew rather than a fault. Under the flag the unknown put is dropped and the
|
|
28
|
+
* rest of the patch resolves, leaving the client without rows for that one
|
|
29
|
+
* query instead of unable to sync anything at all.
|
|
30
|
+
*
|
|
31
|
+
* A query that IS registered but fails to build is a real fault in the app's
|
|
32
|
+
* own code either way, so it always fails the whole patch and names the query.
|
|
20
33
|
*/
|
|
21
|
-
export declare function resolveQueryPatch(patch: readonly unknown[], queries: AnyQueryRegistry, context: unknown, transformVersion: number, fail: (message: string) => Error): unknown[];
|
|
34
|
+
export declare function resolveQueryPatch(patch: readonly unknown[], queries: AnyQueryRegistry, context: unknown, transformVersion: number, fail: (message: string) => Error, tolerateUnknownQueries?: boolean): unknown[];
|
package/dist/query-patch.js
CHANGED
|
@@ -15,18 +15,35 @@ const NAME_SEPARATOR = /[.|]/;
|
|
|
15
15
|
* `asQueryInternals`, whose instance-tag check fails whenever the app's
|
|
16
16
|
* registry and this host resolve different copies of the zero module.
|
|
17
17
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* one unknown query alongside nine good ones is told
|
|
18
|
+
* By default a name the registry does not contain fails the whole patch (the
|
|
19
|
+
* pull is refused as one unit) and the refusal names the query it came from, so
|
|
20
|
+
* a client that registers one unknown query alongside nine good ones is told
|
|
21
|
+
* which one is unknown. Where client and server ship together that is the right
|
|
22
|
+
* answer: an unknown name means the registry was not regenerated, and a loud
|
|
23
|
+
* failure is how the developer finds out.
|
|
24
|
+
*
|
|
25
|
+
* A host that serves independently shipped clients sets
|
|
26
|
+
* `tolerateUnknownQueries`. A native binary is always older than the server it
|
|
27
|
+
* talks to, so it can ask for a query since renamed or removed; that is version
|
|
28
|
+
* skew rather than a fault. Under the flag the unknown put is dropped and the
|
|
29
|
+
* rest of the patch resolves, leaving the client without rows for that one
|
|
30
|
+
* query instead of unable to sync anything at all.
|
|
31
|
+
*
|
|
32
|
+
* A query that IS registered but fails to build is a real fault in the app's
|
|
33
|
+
* own code either way, so it always fails the whole patch and names the query.
|
|
21
34
|
*/
|
|
22
|
-
export function resolveQueryPatch(patch, queries, context, transformVersion, fail) {
|
|
23
|
-
const result = [
|
|
24
|
-
|
|
25
|
-
if (!operation || typeof operation !== 'object')
|
|
26
|
-
|
|
35
|
+
export function resolveQueryPatch(patch, queries, context, transformVersion, fail, tolerateUnknownQueries = false) {
|
|
36
|
+
const result = [];
|
|
37
|
+
for (const operation of patch) {
|
|
38
|
+
if (!operation || typeof operation !== 'object') {
|
|
39
|
+
result.push(operation);
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
27
42
|
const op = operation;
|
|
28
|
-
if (op.op !== 'put')
|
|
29
|
-
|
|
43
|
+
if (op.op !== 'put') {
|
|
44
|
+
result.push(operation);
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
30
47
|
if (typeof op.name !== 'string') {
|
|
31
48
|
throw fail('query put requires a server-resolved named query');
|
|
32
49
|
}
|
|
@@ -41,7 +58,11 @@ export function resolveQueryPatch(patch, queries, context, transformVersion, fai
|
|
|
41
58
|
}
|
|
42
59
|
const custom = node;
|
|
43
60
|
if (!custom || typeof custom.fn !== 'function') {
|
|
44
|
-
|
|
61
|
+
if (!tolerateUnknownQueries)
|
|
62
|
+
throw fail(`unknown or unsupported named query: ${op.name}`);
|
|
63
|
+
// version skew: drop this query and keep syncing the rest.
|
|
64
|
+
console.warn(`orez: dropping unknown named query from pull: ${op.name}`);
|
|
65
|
+
continue;
|
|
45
66
|
}
|
|
46
67
|
let ast;
|
|
47
68
|
try {
|
|
@@ -56,14 +77,14 @@ export function resolveQueryPatch(patch, queries, context, transformVersion, fai
|
|
|
56
77
|
}
|
|
57
78
|
catch (error) {
|
|
58
79
|
const detail = error instanceof Error ? error.message : String(error);
|
|
59
|
-
throw fail(`
|
|
80
|
+
throw fail(`named query failed to build: ${op.name}: ${detail}`);
|
|
60
81
|
}
|
|
61
|
-
result
|
|
82
|
+
result.push({
|
|
62
83
|
op: 'put',
|
|
63
84
|
hash: op.hash,
|
|
64
85
|
ast,
|
|
65
86
|
transformVersion,
|
|
66
|
-
};
|
|
67
|
-
}
|
|
87
|
+
});
|
|
88
|
+
}
|
|
68
89
|
return result;
|
|
69
90
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -106,6 +106,19 @@ export type SyncHostConfig<Env extends SyncHostEnv = SyncHostEnv, S extends Sche
|
|
|
106
106
|
* query context. There is no app endpoint to call and nothing else to wire.
|
|
107
107
|
*/
|
|
108
108
|
queries: AnyQueryRegistry;
|
|
109
|
+
/**
|
|
110
|
+
* Drop a desired query whose name is not in `queries` instead of refusing the
|
|
111
|
+
* whole pull. Off by default, because where the client ships with the server
|
|
112
|
+
* an unknown name means the registry was not regenerated and the request
|
|
113
|
+
* error is how that gets noticed.
|
|
114
|
+
*
|
|
115
|
+
* Set it when the host serves clients that ship on their own schedule, such
|
|
116
|
+
* as a native app in an app store. Those clients are routinely older than the
|
|
117
|
+
* server and will ask for queries that have since been renamed or removed;
|
|
118
|
+
* without this the pull is refused as one unit and an app one feature out of
|
|
119
|
+
* date cannot sync anything at all.
|
|
120
|
+
*/
|
|
121
|
+
tolerateUnknownQueries?: boolean;
|
|
109
122
|
/**
|
|
110
123
|
* Streaming fields for this namespace: which columns may carry a live,
|
|
111
124
|
* uncommitted value, and their publish mode and rate bounds.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "orez-sync-cf-host",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.2",
|
|
4
4
|
"description": "Internal orez Cloudflare sync host. Do not import directly: consumers use orez-lite/cloudflare/sync.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"bundle": "bun run build:dist && wrangler deploy --dry-run --outdir .wrangler/bundle",
|
|
49
49
|
"measure": "bun run build:dist && bun measure.mjs",
|
|
50
50
|
"test": "bun run test:config && bun run test:query-compiler && bun run test:package && bun run test:platform && bun run test:integration && bun run test:large-data && bun run test:ingest && bun run test:restart",
|
|
51
|
-
"test:config": "bun test config.test.mjs write-safeguards.test.mjs transaction-query.test.mjs upstream-response.test.mjs serving-lag.test.mjs",
|
|
51
|
+
"test:config": "bun test config.test.mjs query-patch.test.mjs write-safeguards.test.mjs transaction-query.test.mjs upstream-response.test.mjs serving-lag.test.mjs",
|
|
52
52
|
"test:integration": "bun run build:dist && bun integration-test.mjs",
|
|
53
53
|
"test:ingest": "bun run build:dist && bun ingest-test.mjs",
|
|
54
54
|
"test:package": "bun run build:dist && node package-runtime-test.mjs",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
},
|
|
61
61
|
"dependencies": {
|
|
62
62
|
"@opentelemetry/api": "^1.9.0",
|
|
63
|
-
"orez-sync-executor": "0.16.
|
|
63
|
+
"orez-sync-executor": "0.16.2"
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|
|
66
66
|
"@cloudflare/workers-types": "4.20260617.1",
|