@syncular/core 0.0.6-96 → 0.1.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/blobs.d.ts +14 -7
- package/dist/blobs.d.ts.map +1 -1
- package/dist/blobs.js.map +1 -1
- package/dist/column-codecs.d.ts +3 -0
- package/dist/column-codecs.d.ts.map +1 -1
- package/dist/column-codecs.js +32 -4
- package/dist/column-codecs.js.map +1 -1
- package/dist/conflict.js.map +1 -1
- package/dist/database.js +1 -1
- package/dist/database.js.map +1 -1
- package/dist/error-responses.d.ts +393 -0
- package/dist/error-responses.d.ts.map +1 -0
- package/dist/error-responses.js +393 -0
- package/dist/error-responses.js.map +1 -0
- package/dist/http/api-client.d.ts +11 -0
- package/dist/http/api-client.d.ts.map +1 -0
- package/dist/http/api-client.js +30 -0
- package/dist/http/api-client.js.map +1 -0
- package/dist/http/blob.d.ts +6 -0
- package/dist/http/blob.d.ts.map +1 -0
- package/dist/http/blob.js +46 -0
- package/dist/http/blob.js.map +1 -0
- package/dist/http/generated/api.d.ts +5241 -0
- package/dist/http/generated/api.d.ts.map +1 -0
- package/dist/http/generated/api.js +6 -0
- package/dist/http/generated/api.js.map +1 -0
- package/dist/http/index.d.ts +18 -0
- package/dist/http/index.d.ts.map +1 -0
- package/dist/http/index.js +212 -0
- package/dist/http/index.js.map +1 -0
- package/dist/http/shared.d.ts +45 -0
- package/dist/http/shared.d.ts.map +1 -0
- package/dist/http/shared.js +122 -0
- package/dist/http/shared.js.map +1 -0
- package/dist/http/transport-client.d.ts +31 -0
- package/dist/http/transport-client.d.ts.map +1 -0
- package/dist/http/transport-client.js +193 -0
- package/dist/http/transport-client.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -15
- package/dist/index.js.map +1 -1
- package/dist/kysely-column-codecs.d.ts +17 -1
- package/dist/kysely-column-codecs.d.ts.map +1 -1
- package/dist/kysely-column-codecs.js +56 -70
- package/dist/kysely-column-codecs.js.map +1 -1
- package/dist/logger.js +1 -1
- package/dist/logger.js.map +1 -1
- package/dist/schemas/blobs.d.ts +7 -1
- package/dist/schemas/blobs.d.ts.map +1 -1
- package/dist/schemas/blobs.js +1 -0
- package/dist/schemas/blobs.js.map +1 -1
- package/dist/schemas/common.d.ts +73 -1
- package/dist/schemas/common.d.ts.map +1 -1
- package/dist/schemas/common.js +38 -0
- package/dist/schemas/common.js.map +1 -1
- package/dist/schemas/index.js +3 -3
- package/dist/schemas/sync.d.ts +712 -38
- package/dist/schemas/sync.d.ts.map +1 -1
- package/dist/schemas/sync.js +209 -5
- package/dist/schemas/sync.js.map +1 -1
- package/dist/scopes/index.d.ts +5 -0
- package/dist/scopes/index.d.ts.map +1 -1
- package/dist/scopes/index.js +27 -0
- package/dist/scopes/index.js.map +1 -1
- package/dist/sentry.d.ts +31 -0
- package/dist/sentry.d.ts.map +1 -0
- package/dist/sentry.js +147 -0
- package/dist/sentry.js.map +1 -0
- package/dist/snapshot-chunks.d.ts +104 -20
- package/dist/snapshot-chunks.d.ts.map +1 -1
- package/dist/snapshot-chunks.js +665 -72
- package/dist/snapshot-chunks.js.map +1 -1
- package/dist/sync-packs.d.ts +33 -0
- package/dist/sync-packs.d.ts.map +1 -0
- package/dist/sync-packs.js +821 -0
- package/dist/sync-packs.js.map +1 -0
- package/dist/telemetry.d.ts.map +1 -1
- package/dist/telemetry.js +3 -2
- package/dist/telemetry.js.map +1 -1
- package/dist/transforms.js.map +1 -1
- package/dist/types.d.ts +48 -7
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/bytes.d.ts +4 -0
- package/dist/utils/bytes.d.ts.map +1 -0
- package/dist/utils/bytes.js +66 -0
- package/dist/utils/bytes.js.map +1 -0
- package/dist/utils/compression.d.ts +11 -3
- package/dist/utils/compression.d.ts.map +1 -1
- package/dist/utils/compression.js +102 -50
- package/dist/utils/compression.js.map +1 -1
- package/dist/utils/crypto.d.ts +7 -1
- package/dist/utils/crypto.d.ts.map +1 -1
- package/dist/utils/crypto.js +89 -7
- package/dist/utils/crypto.js.map +1 -1
- package/dist/utils/id.d.ts.map +1 -1
- package/dist/utils/id.js +4 -1
- package/dist/utils/id.js.map +1 -1
- package/dist/utils/index.d.ts +5 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +9 -4
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/internal-runtime.d.ts +16 -0
- package/dist/utils/internal-runtime.d.ts.map +1 -0
- package/dist/utils/internal-runtime.js +14 -0
- package/dist/utils/internal-runtime.js.map +1 -0
- package/dist/utils/object.js.map +1 -1
- package/dist/utils/realtime-change-index.d.ts +9 -0
- package/dist/utils/realtime-change-index.d.ts.map +1 -0
- package/dist/utils/realtime-change-index.js +36 -0
- package/dist/utils/realtime-change-index.js.map +1 -0
- package/dist/utils/realtime-connection-registry.d.ts +40 -0
- package/dist/utils/realtime-connection-registry.d.ts.map +1 -0
- package/dist/utils/realtime-connection-registry.js +237 -0
- package/dist/utils/realtime-connection-registry.js.map +1 -0
- package/dist/utils/table-registry.d.ts +10 -0
- package/dist/utils/table-registry.d.ts.map +1 -0
- package/dist/utils/table-registry.js +54 -0
- package/dist/utils/table-registry.js.map +1 -0
- package/dist/utils/url.d.ts +3 -0
- package/dist/utils/url.d.ts.map +1 -0
- package/dist/utils/url.js +20 -0
- package/dist/utils/url.js.map +1 -0
- package/package.json +52 -7
- package/src/blobs.ts +24 -7
- package/src/column-codecs.ts +36 -8
- package/src/error-responses.ts +423 -0
- package/src/http/api-client.ts +39 -0
- package/src/http/blob.ts +95 -0
- package/src/http/generated/api.ts +5241 -0
- package/src/http/index.ts +365 -0
- package/src/http/shared.ts +220 -0
- package/src/http/transport-client.ts +314 -0
- package/src/index.ts +4 -0
- package/src/kysely-column-codecs.ts +81 -86
- package/src/schemas/blobs.ts +10 -1
- package/src/schemas/common.ts +44 -0
- package/src/schemas/sync.ts +298 -7
- package/src/scopes/index.ts +42 -0
- package/src/sentry.ts +200 -0
- package/src/snapshot-chunks.ts +921 -69
- package/src/sync-packs.ts +1096 -0
- package/src/telemetry.ts +7 -2
- package/src/types.ts +63 -8
- package/src/utils/bytes.ts +75 -0
- package/src/utils/compression.ts +147 -51
- package/src/utils/crypto.ts +120 -7
- package/src/utils/id.ts +11 -1
- package/src/utils/index.ts +5 -0
- package/src/utils/internal-runtime.ts +39 -0
- package/src/utils/realtime-change-index.ts +44 -0
- package/src/utils/realtime-connection-registry.ts +286 -0
- package/src/utils/table-registry.ts +67 -0
- package/src/utils/url.ts +29 -0
- package/src/__tests__/compression.test.ts +0 -54
- package/src/__tests__/conflict.test.ts +0 -325
- package/src/__tests__/telemetry.test.ts +0 -170
- package/src/__tests__/utils.test.ts +0 -27
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export function registerTableOrThrow(registeredTables, table, duplicateTableError) {
|
|
2
|
+
if (registeredTables.has(table))
|
|
3
|
+
throw new Error(duplicateTableError(table));
|
|
4
|
+
registeredTables.add(table);
|
|
5
|
+
}
|
|
6
|
+
export function createTableLookup(handlers, duplicateTableError) {
|
|
7
|
+
const byTable = new Map();
|
|
8
|
+
for (const handler of handlers) {
|
|
9
|
+
if (byTable.has(handler.table)) {
|
|
10
|
+
throw new Error(duplicateTableError(handler.table));
|
|
11
|
+
}
|
|
12
|
+
byTable.set(handler.table, handler);
|
|
13
|
+
}
|
|
14
|
+
return byTable;
|
|
15
|
+
}
|
|
16
|
+
export function assertKnownTableDependencies(handlers, byTable, unknownDependencyError) {
|
|
17
|
+
for (const handler of handlers) {
|
|
18
|
+
for (const dependency of handler.dependsOn ?? []) {
|
|
19
|
+
if (!byTable.has(dependency)) {
|
|
20
|
+
throw new Error(unknownDependencyError(handler.table, dependency));
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export function topologicallySortTablesByDependencies(byTable, targetTable) {
|
|
26
|
+
const visited = new Set();
|
|
27
|
+
const visiting = new Set();
|
|
28
|
+
const sorted = [];
|
|
29
|
+
const visit = (table) => {
|
|
30
|
+
if (visited.has(table))
|
|
31
|
+
return;
|
|
32
|
+
if (visiting.has(table)) {
|
|
33
|
+
throw new Error(`Circular dependency detected involving table "${table}"`);
|
|
34
|
+
}
|
|
35
|
+
const handler = byTable.get(table);
|
|
36
|
+
if (!handler)
|
|
37
|
+
throw new Error(`Unknown table: ${table}`);
|
|
38
|
+
visiting.add(table);
|
|
39
|
+
for (const dependency of handler.dependsOn ?? [])
|
|
40
|
+
visit(dependency);
|
|
41
|
+
visiting.delete(table);
|
|
42
|
+
visited.add(table);
|
|
43
|
+
sorted.push(handler);
|
|
44
|
+
};
|
|
45
|
+
if (targetTable) {
|
|
46
|
+
visit(targetTable);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
for (const table of byTable.keys())
|
|
50
|
+
visit(table);
|
|
51
|
+
}
|
|
52
|
+
return sorted;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=table-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"table-registry.js","sourceRoot":"","sources":["../../src/utils/table-registry.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,oBAAoB,CAClC,gBAA6B,EAC7B,KAAa,EACb,mBAA8C;IAE9C,IAAI,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC;IAC7E,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAC9B,CAAC;AACD,MAAM,UAAU,iBAAiB,CAC/B,QAAsB,EACtB,mBAA8C;IAE9C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAa,CAAC;IACrC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;QACtD,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AACD,MAAM,UAAU,4BAA4B,CAC1C,QAAsB,EACtB,OAA+B,EAC/B,sBAAqE;IAErE,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,KAAK,MAAM,UAAU,IAAI,OAAO,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC;YACjD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC7B,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,OAAO,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC;YACrE,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AACD,MAAM,UAAU,qCAAqC,CACnD,OAA+B,EAC/B,WAAoB;IAEpB,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;IACnC,MAAM,MAAM,GAAQ,EAAE,CAAC;IACvB,MAAM,KAAK,GAAG,CAAC,KAAa,EAAE,EAAE;QAC9B,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,OAAO;QAC/B,IAAI,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CACb,iDAAiD,KAAK,GAAG,CAC1D,CAAC;QACJ,CAAC;QACD,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,kBAAkB,KAAK,EAAE,CAAC,CAAC;QACzD,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACpB,KAAK,MAAM,UAAU,IAAI,OAAO,CAAC,SAAS,IAAI,EAAE;YAAE,KAAK,CAAC,UAAU,CAAC,CAAC;QACpE,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACnB,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACvB,CAAC,CAAC;IACF,IAAI,WAAW,EAAE,CAAC;QAChB,KAAK,CAAC,WAAW,CAAC,CAAC;IACrB,CAAC;SAAM,CAAC;QACN,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,IAAI,EAAE;YAAE,KAAK,CAAC,KAAK,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"url.d.ts","sourceRoot":"","sources":["../../src/utils/url.ts"],"names":[],"mappings":"AAKA,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAKxD;AAED,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,MAAM,GACd,MAAM,CAYR"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const ABSOLUTE_URL_SCHEME_REGEX = /^[a-zA-Z][a-zA-Z0-9+.-]*:/;
|
|
2
|
+
const trimTrailingSlashes = (value) => value.replace(/\/+$/, '');
|
|
3
|
+
export function normalizeSyncBaseUrl(url) {
|
|
4
|
+
const trimmed = trimTrailingSlashes(url.trim());
|
|
5
|
+
if (!trimmed.endsWith('/sync'))
|
|
6
|
+
return trimmed;
|
|
7
|
+
const baseUrl = trimmed.slice(0, -'/sync'.length);
|
|
8
|
+
return baseUrl.length > 0 ? baseUrl : '/';
|
|
9
|
+
}
|
|
10
|
+
export function resolveUrlFromBase(baseUrl, path, origin) {
|
|
11
|
+
const normalizedPath = path.replace(/^\/+/, '');
|
|
12
|
+
const normalizedBaseUrl = trimTrailingSlashes(baseUrl);
|
|
13
|
+
if (ABSOLUTE_URL_SCHEME_REGEX.test(baseUrl)) {
|
|
14
|
+
return new URL(normalizedPath, baseUrl.endsWith('/') ? baseUrl : `${baseUrl}/`).toString();
|
|
15
|
+
}
|
|
16
|
+
if (origin)
|
|
17
|
+
return new URL(`${normalizedBaseUrl}/${normalizedPath}`, origin).toString();
|
|
18
|
+
return `${normalizedBaseUrl}/${normalizedPath}`;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=url.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"url.js","sourceRoot":"","sources":["../../src/utils/url.ts"],"names":[],"mappings":"AAAA,MAAM,yBAAyB,GAAG,2BAA2B,CAAC;AAE9D,MAAM,mBAAmB,GAAG,CAAC,KAAa,EAAU,EAAE,CACpD,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AAE5B,MAAM,UAAU,oBAAoB,CAAC,GAAW;IAC9C,MAAM,OAAO,GAAG,mBAAmB,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;IAChD,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAC;IAC/C,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAClD,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,OAAe,EACf,IAAY,EACZ,MAAe;IAEf,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAChD,MAAM,iBAAiB,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;IACvD,IAAI,yBAAyB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5C,OAAO,IAAI,GAAG,CACZ,cAAc,EACd,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,GAAG,CAChD,CAAC,QAAQ,EAAE,CAAC;IACf,CAAC;IACD,IAAI,MAAM;QACR,OAAO,IAAI,GAAG,CAAC,GAAG,iBAAiB,IAAI,cAAc,EAAE,EAAE,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC9E,OAAO,GAAG,iBAAiB,IAAI,cAAc,EAAE,CAAC;AAClD,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@syncular/core",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "Core protocol types and shared utilities for the Syncular sync framework",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Benjamin Kniffler",
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"typescript"
|
|
22
22
|
],
|
|
23
23
|
"private": false,
|
|
24
|
+
"sideEffects": false,
|
|
24
25
|
"publishConfig": {
|
|
25
26
|
"access": "public"
|
|
26
27
|
},
|
|
@@ -33,25 +34,69 @@
|
|
|
33
34
|
"types": "./dist/index.d.ts",
|
|
34
35
|
"default": "./dist/index.js"
|
|
35
36
|
}
|
|
37
|
+
},
|
|
38
|
+
"./http": {
|
|
39
|
+
"bun": "./src/http/index.ts",
|
|
40
|
+
"browser": "./src/http/index.ts",
|
|
41
|
+
"import": {
|
|
42
|
+
"types": "./dist/http/index.d.ts",
|
|
43
|
+
"default": "./dist/http/index.js"
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"./http/blob": {
|
|
47
|
+
"bun": "./src/http/blob.ts",
|
|
48
|
+
"browser": "./src/http/blob.ts",
|
|
49
|
+
"import": {
|
|
50
|
+
"types": "./dist/http/blob.d.ts",
|
|
51
|
+
"default": "./dist/http/blob.js"
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
"./sentry": {
|
|
55
|
+
"bun": "./src/sentry.ts",
|
|
56
|
+
"browser": "./src/sentry.ts",
|
|
57
|
+
"import": {
|
|
58
|
+
"types": "./dist/sentry.d.ts",
|
|
59
|
+
"default": "./dist/sentry.js"
|
|
60
|
+
}
|
|
36
61
|
}
|
|
37
62
|
},
|
|
38
63
|
"scripts": {
|
|
64
|
+
"fixtures:protocol": "bun scripts/generate-protocol-fixtures.ts",
|
|
39
65
|
"test": "bun test src/__tests__",
|
|
40
66
|
"tsgo": "tsgo --noEmit",
|
|
41
67
|
"build": "tsgo",
|
|
42
|
-
"release": "
|
|
68
|
+
"release": "syncular-publish",
|
|
69
|
+
"generate:http-types": "openapi-typescript ../server/openapi.json -o src/http/generated/api.ts"
|
|
43
70
|
},
|
|
44
71
|
"peerDependencies": {
|
|
45
72
|
"kysely": "^0.28.0",
|
|
46
|
-
"zod": "^4.0.0"
|
|
73
|
+
"zod": "^4.0.0",
|
|
74
|
+
"openapi-fetch": "^0.17.0"
|
|
47
75
|
},
|
|
48
76
|
"devDependencies": {
|
|
49
|
-
"@syncular/config": "
|
|
77
|
+
"@syncular/config": "workspace:*",
|
|
50
78
|
"kysely": "*",
|
|
51
|
-
"zod": "*"
|
|
79
|
+
"zod": "*",
|
|
80
|
+
"openapi-fetch": "^0.17.0",
|
|
81
|
+
"openapi-typescript": "^7.13.0"
|
|
52
82
|
},
|
|
53
83
|
"files": [
|
|
54
84
|
"dist",
|
|
55
|
-
"src"
|
|
56
|
-
|
|
85
|
+
"src",
|
|
86
|
+
"!src/**/*.test.ts",
|
|
87
|
+
"!src/**/*.test.tsx",
|
|
88
|
+
"!src/**/__tests__/**",
|
|
89
|
+
"!dist/**/*.test.*",
|
|
90
|
+
"!dist/**/__tests__/**",
|
|
91
|
+
"!test/**",
|
|
92
|
+
"!tests/**"
|
|
93
|
+
],
|
|
94
|
+
"dependencies": {
|
|
95
|
+
"fflate": "^0.8.2"
|
|
96
|
+
},
|
|
97
|
+
"peerDependenciesMeta": {
|
|
98
|
+
"openapi-fetch": {
|
|
99
|
+
"optional": true
|
|
100
|
+
}
|
|
101
|
+
}
|
|
57
102
|
}
|
package/src/blobs.ts
CHANGED
|
@@ -56,6 +56,8 @@ export interface BlobTransport {
|
|
|
56
56
|
export interface BlobSignUploadOptions {
|
|
57
57
|
/** SHA-256 hash (for naming and checksum validation) */
|
|
58
58
|
hash: string;
|
|
59
|
+
/** Optional tenant/partition namespace for storage lookups */
|
|
60
|
+
partitionId?: string;
|
|
59
61
|
/** Content size in bytes */
|
|
60
62
|
size: number;
|
|
61
63
|
/** MIME type */
|
|
@@ -82,10 +84,16 @@ export interface BlobSignedUpload {
|
|
|
82
84
|
export interface BlobSignDownloadOptions {
|
|
83
85
|
/** SHA-256 hash */
|
|
84
86
|
hash: string;
|
|
87
|
+
/** Optional tenant/partition namespace for storage lookups */
|
|
88
|
+
partitionId?: string;
|
|
85
89
|
/** URL expiration in seconds */
|
|
86
90
|
expiresIn: number;
|
|
87
91
|
}
|
|
88
92
|
|
|
93
|
+
export interface BlobStoragePartitionOptions {
|
|
94
|
+
partitionId?: string;
|
|
95
|
+
}
|
|
96
|
+
|
|
89
97
|
/**
|
|
90
98
|
* Adapter for blob storage backends (S3, R2, custom).
|
|
91
99
|
* Implementations handle actual storage; the sync server orchestrates.
|
|
@@ -108,19 +116,20 @@ export interface BlobStorageAdapter {
|
|
|
108
116
|
/**
|
|
109
117
|
* Check if a blob exists in storage.
|
|
110
118
|
*/
|
|
111
|
-
exists(hash: string): Promise<boolean>;
|
|
119
|
+
exists(hash: string, options?: BlobStoragePartitionOptions): Promise<boolean>;
|
|
112
120
|
|
|
113
121
|
/**
|
|
114
122
|
* Delete a blob (for garbage collection).
|
|
115
123
|
*/
|
|
116
|
-
delete(hash: string): Promise<void>;
|
|
124
|
+
delete(hash: string, options?: BlobStoragePartitionOptions): Promise<void>;
|
|
117
125
|
|
|
118
126
|
/**
|
|
119
127
|
* Get blob metadata from storage (optional).
|
|
120
128
|
* Used to verify uploads completed successfully.
|
|
121
129
|
*/
|
|
122
130
|
getMetadata?(
|
|
123
|
-
hash: string
|
|
131
|
+
hash: string,
|
|
132
|
+
options?: BlobStoragePartitionOptions
|
|
124
133
|
): Promise<{ size: number; mimeType?: string } | null>;
|
|
125
134
|
|
|
126
135
|
/**
|
|
@@ -130,7 +139,8 @@ export interface BlobStorageAdapter {
|
|
|
130
139
|
put?(
|
|
131
140
|
hash: string,
|
|
132
141
|
data: Uint8Array,
|
|
133
|
-
metadata?: Record<string, unknown
|
|
142
|
+
metadata?: Record<string, unknown>,
|
|
143
|
+
options?: BlobStoragePartitionOptions
|
|
134
144
|
): Promise<void>;
|
|
135
145
|
|
|
136
146
|
/**
|
|
@@ -140,18 +150,25 @@ export interface BlobStorageAdapter {
|
|
|
140
150
|
putStream?(
|
|
141
151
|
hash: string,
|
|
142
152
|
stream: ReadableStream<Uint8Array>,
|
|
143
|
-
metadata?: Record<string, unknown
|
|
153
|
+
metadata?: Record<string, unknown>,
|
|
154
|
+
options?: BlobStoragePartitionOptions
|
|
144
155
|
): Promise<void>;
|
|
145
156
|
|
|
146
157
|
/**
|
|
147
158
|
* Get blob data directly (for adapters that support direct retrieval).
|
|
148
159
|
*/
|
|
149
|
-
get?(
|
|
160
|
+
get?(
|
|
161
|
+
hash: string,
|
|
162
|
+
options?: BlobStoragePartitionOptions
|
|
163
|
+
): Promise<Uint8Array | null>;
|
|
150
164
|
|
|
151
165
|
/**
|
|
152
166
|
* Get blob data directly as a stream (for adapters that support stream retrieval).
|
|
153
167
|
*/
|
|
154
|
-
getStream?(
|
|
168
|
+
getStream?(
|
|
169
|
+
hash: string,
|
|
170
|
+
options?: BlobStoragePartitionOptions
|
|
171
|
+
): Promise<ReadableStream<Uint8Array> | null>;
|
|
155
172
|
}
|
|
156
173
|
|
|
157
174
|
// ============================================================================
|
package/src/column-codecs.ts
CHANGED
|
@@ -88,6 +88,35 @@ export function toTableColumnCodecs(
|
|
|
88
88
|
return out;
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
+
export function createTableColumnCodecsResolver(
|
|
92
|
+
codecSource: ColumnCodecSource | undefined,
|
|
93
|
+
options: { dialect?: ColumnCodecDialect } = {}
|
|
94
|
+
): (table: string, row: Record<string, unknown>) => TableColumnCodecs {
|
|
95
|
+
const tableCaches = new Map<string, Map<string, TableColumnCodecs>>();
|
|
96
|
+
|
|
97
|
+
return (table, row) => {
|
|
98
|
+
if (!codecSource) return {};
|
|
99
|
+
const columns = Object.keys(row);
|
|
100
|
+
if (columns.length === 0) return {};
|
|
101
|
+
|
|
102
|
+
const cacheKey = columns.slice().sort().join('\u0000');
|
|
103
|
+
let perTableCache = tableCaches.get(table);
|
|
104
|
+
if (!perTableCache) {
|
|
105
|
+
perTableCache = new Map<string, TableColumnCodecs>();
|
|
106
|
+
tableCaches.set(table, perTableCache);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const cached = perTableCache.get(cacheKey);
|
|
110
|
+
if (cached) return cached;
|
|
111
|
+
|
|
112
|
+
const resolved = toTableColumnCodecs(table, codecSource, columns, {
|
|
113
|
+
dialect: options.dialect,
|
|
114
|
+
});
|
|
115
|
+
perTableCache.set(cacheKey, resolved);
|
|
116
|
+
return resolved;
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
91
120
|
export function applyCodecToDbValue(
|
|
92
121
|
codec: AnyColumnCodec,
|
|
93
122
|
value: unknown,
|
|
@@ -134,16 +163,15 @@ export function applyCodecsFromDbRow(
|
|
|
134
163
|
): Record<string, unknown> {
|
|
135
164
|
if (!hasCodecs(tableCodecs)) return { ...row };
|
|
136
165
|
|
|
137
|
-
|
|
166
|
+
let transformed: Record<string, unknown> | null = null;
|
|
138
167
|
for (const [column, codec] of Object.entries(tableCodecs)) {
|
|
139
|
-
if (!(column in
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
);
|
|
168
|
+
if (!(column in row)) continue;
|
|
169
|
+
const value = row[column];
|
|
170
|
+
if (value === null || value === undefined) continue;
|
|
171
|
+
transformed ??= { ...row };
|
|
172
|
+
transformed[column] = applyCodecFromDbValue(codec, value, dialect);
|
|
145
173
|
}
|
|
146
|
-
return transformed;
|
|
174
|
+
return transformed ?? row;
|
|
147
175
|
}
|
|
148
176
|
|
|
149
177
|
function parseBooleanValue(value: unknown): boolean {
|