@lunora/do 1.0.0-alpha.44 → 1.0.0-alpha.45
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/index.d.mts +55 -1
- package/dist/index.d.ts +55 -1
- package/dist/index.mjs +1 -44
- package/dist/packem_shared/ADMIN_FUNCTIONS-PxZ8Lr9e.mjs +1 -0
- package/dist/packem_shared/AGGREGATE_SQL_FUNCTION-QYaiuty4.mjs +1 -0
- package/dist/packem_shared/AUTH_METRICS_BUCKETS_TABLE-D0wNaez7.mjs +22 -0
- package/dist/packem_shared/CDC_LOG_TABLE-E_J5LPoK.mjs +8 -0
- package/dist/packem_shared/ConflictError-C8GtJmjS.mjs +1 -0
- package/dist/packem_shared/CountRlsUnsupportedError-Cl8XpYDL.mjs +1 -0
- package/dist/packem_shared/DATA_MIGRATION_STATE_TABLE-CaO6L0Ee.mjs +31 -0
- package/dist/packem_shared/DEFAULT_MAX_RELATION_KEYS-BRdmX7WW.mjs +1 -0
- package/dist/packem_shared/FUNCTION_METRICS_BUCKETS_TABLE-BPPeqM11.mjs +56 -0
- package/dist/packem_shared/GEO_DEFAULT_PRECISION-CWAm_oYY.mjs +1 -0
- package/dist/packem_shared/LogBuffer-bIvCelI-.mjs +1 -0
- package/dist/packem_shared/MAIL_RETENTION-KmozO2NQ.mjs +18 -0
- package/dist/packem_shared/MAX_SQL_ROWS-Bdu25ASB.mjs +2 -0
- package/dist/packem_shared/MIN_ADMIN_TOKEN_LENGTH-Ch6OW6_3.mjs +1 -0
- package/dist/packem_shared/NotFoundError-J3tjf4Uo.mjs +1 -0
- package/dist/packem_shared/NotUniqueError-BcP6GOem.mjs +1 -0
- package/dist/packem_shared/RANK_TIEBREAK-DtX8zQyc.mjs +1 -0
- package/dist/packem_shared/RLS_UNWRAP_SYMBOL-C6_WX3dG.mjs +1 -0
- package/dist/packem_shared/ROOT_DO_SIZE_WARN_BYTES-CP5wvJOW.mjs +101 -0
- package/dist/packem_shared/ReactiveCache-1_9Rs7J_.mjs +1 -0
- package/dist/packem_shared/SCAN_DEP-D_yR9EeV.mjs +1 -0
- package/dist/packem_shared/SESSION_DO_TTL_DEFAULT-GvBy_DBz.mjs +1 -0
- package/dist/packem_shared/SHARD_REGISTRY_DO_NAME-Caa0fR4N.mjs +1 -0
- package/dist/packem_shared/aggregateTableName-G-eXyjcz.mjs +1 -0
- package/dist/packem_shared/applyOnDelete-BvQN7pDL.mjs +1 -0
- package/dist/packem_shared/applySelect-Bq2KOrkL.mjs +1 -0
- package/dist/packem_shared/armRestore-BNzdvQ_o.mjs +1 -0
- package/dist/packem_shared/backfillAggregateIndexes-BAQ3Fwwh.mjs +1 -0
- package/dist/packem_shared/buildFtsMatch-CV0Z7PWv.mjs +1 -0
- package/dist/packem_shared/compileWhereSql-BLcfs4QW.mjs +1 -0
- package/dist/packem_shared/constant-time-equal-BVG05Guz.mjs +1 -0
- package/dist/packem_shared/context-telemetry-8eigmiNQ.mjs +1 -0
- package/dist/packem_shared/createMetrics-CyjLFXtA.mjs +1 -0
- package/dist/packem_shared/createSystemReader-DcDcrtM3.mjs +1 -0
- package/dist/packem_shared/ctx-db-idempotency-wiVoGnpQ.mjs +19 -0
- package/dist/packem_shared/ctx-db-shapes-DzX_H5q8.mjs +1 -0
- package/dist/packem_shared/diffExternalSource-DMpkJta1.mjs +1 -0
- package/dist/packem_shared/do-exec-BLe9lLrN.mjs +1 -0
- package/dist/packem_shared/do-sql-BYIQTG3z.mjs +1 -0
- package/dist/packem_shared/exportShardRows-kt42wijd.mjs +1 -0
- package/dist/packem_shared/hasTrigger-_rexbWMO.mjs +1 -0
- package/dist/packem_shared/isSoftDeleted-BvhQov04.mjs +9 -0
- package/dist/packem_shared/json-response-wrh9TBPw.mjs +1 -0
- package/dist/packem_shared/materializeExternalRows-BFmT9gsw.mjs +1 -0
- package/dist/packem_shared/renderSql-B5lF5Jd9.mjs +1 -0
- package/dist/packem_shared/runShardMigrations-bxOHpfID.mjs +5 -0
- package/dist/packem_shared/security-audit-BKUOgE0x.mjs +1 -0
- package/dist/packem_shared/selectExpiredIds-BGVP3d8-.mjs +1 -0
- package/dist/packem_shared/serialize-sql-DiRzL7A4.mjs +1 -0
- package/dist/packem_shared/serveRelationFanout-Ct5D2Tbk.mjs +1 -0
- package/dist/packem_shared/stableStringify-BjLh4gvA.mjs +1 -0
- package/dist/packem_shared/stableWireKey-YEHLaX6X.mjs +1 -0
- package/dist/packem_shared/subscriptionListDeltas-Bs69JbA8.mjs +1 -0
- package/dist/packem_shared/wire-codec-Ctnni0h6.mjs +1 -0
- package/package.json +1 -1
- package/dist/packem_shared/ADMIN_FUNCTIONS-CnZkbXH_.mjs +0 -374
- package/dist/packem_shared/AGGREGATE_SQL_FUNCTION-CQsu2Xga.mjs +0 -56
- package/dist/packem_shared/AUTH_METRICS_BUCKETS_TABLE-CiHHYeJi.mjs +0 -84
- package/dist/packem_shared/CDC_LOG_TABLE-uwOJxJJZ.mjs +0 -107
- package/dist/packem_shared/ConflictError-CLoq37xH.mjs +0 -12
- package/dist/packem_shared/CountRlsUnsupportedError-BGxj0pgS.mjs +0 -133
- package/dist/packem_shared/DATA_MIGRATION_STATE_TABLE-CYwBpyTr.mjs +0 -245
- package/dist/packem_shared/DEFAULT_MAX_RELATION_KEYS-BEan1CRD.mjs +0 -211
- package/dist/packem_shared/FUNCTION_METRICS_BUCKETS_TABLE-UDNVD7FS.mjs +0 -248
- package/dist/packem_shared/GEO_DEFAULT_PRECISION-BWnsNmpP.mjs +0 -114
- package/dist/packem_shared/LogBuffer-B_Ezju_N.mjs +0 -37
- package/dist/packem_shared/MAIL_RETENTION-CPpgl-dX.mjs +0 -104
- package/dist/packem_shared/MAX_SQL_ROWS-iFAA8FbD.mjs +0 -61
- package/dist/packem_shared/MIN_ADMIN_TOKEN_LENGTH-CCAvoFlr.mjs +0 -1
- package/dist/packem_shared/NotFoundError-C70b9hLw.mjs +0 -9
- package/dist/packem_shared/NotUniqueError-DbtlWwcG.mjs +0 -2031
- package/dist/packem_shared/RANK_TIEBREAK-CXhdcA1o.mjs +0 -91
- package/dist/packem_shared/RLS_UNWRAP_SYMBOL-DTvHvRzY.mjs +0 -141
- package/dist/packem_shared/ROOT_DO_SIZE_WARN_BYTES-B_zt4RQE.mjs +0 -7676
- package/dist/packem_shared/ReactiveCache-DnSvbjil.mjs +0 -233
- package/dist/packem_shared/SCAN_DEP-DLJF8dsj.mjs +0 -19
- package/dist/packem_shared/SESSION_DO_TTL_DEFAULT-BnSKgVO4.mjs +0 -169
- package/dist/packem_shared/SHARD_REGISTRY_DO_NAME-D99roc-r.mjs +0 -144
- package/dist/packem_shared/aggregateTableName-CxNqY1Sl.mjs +0 -64
- package/dist/packem_shared/applyOnDelete-BXSq3S70.mjs +0 -176
- package/dist/packem_shared/applySelect-WQY8m62C.mjs +0 -103
- package/dist/packem_shared/armRestore-4Px61hHS.mjs +0 -49
- package/dist/packem_shared/backfillAggregateIndexes-BGTwynwh.mjs +0 -81
- package/dist/packem_shared/buildFtsMatch-BLEMawrp.mjs +0 -38
- package/dist/packem_shared/compileWhereSql-DE6yfRcQ.mjs +0 -129
- package/dist/packem_shared/constant-time-equal-BVRWZgES.mjs +0 -12
- package/dist/packem_shared/context-telemetry-CDpyil58.mjs +0 -223
- package/dist/packem_shared/createMetrics-C4I2Yanj.mjs +0 -1
- package/dist/packem_shared/createSystemReader-D12eNH13.mjs +0 -82
- package/dist/packem_shared/ctx-db-idempotency-BdcNpvY4.mjs +0 -108
- package/dist/packem_shared/ctx-db-shapes-DTeFiHYS.mjs +0 -53
- package/dist/packem_shared/diffExternalSource-CovHfdyo.mjs +0 -44
- package/dist/packem_shared/do-exec-5eQy5cEi.mjs +0 -12
- package/dist/packem_shared/do-sql-CGAgiQUz.mjs +0 -88
- package/dist/packem_shared/exportShardRows-Dy3oFZ26.mjs +0 -157
- package/dist/packem_shared/hasTrigger-5N6_Fx0A.mjs +0 -20
- package/dist/packem_shared/isSoftDeleted-CFJmhjFP.mjs +0 -217
- package/dist/packem_shared/json-response-BdbtpOhm.mjs +0 -3
- package/dist/packem_shared/materializeExternalRows-BtEGs1Fv.mjs +0 -45
- package/dist/packem_shared/renderSql-D6eUcn2N.mjs +0 -16
- package/dist/packem_shared/runShardMigrations-BVax6rYu.mjs +0 -120
- package/dist/packem_shared/security-audit-CucgBice.mjs +0 -158
- package/dist/packem_shared/selectExpiredIds-C5W29Upb.mjs +0 -18
- package/dist/packem_shared/serialize-sql-BlRUoiQe.mjs +0 -14
- package/dist/packem_shared/serveRelationFanout-k7HTh3CC.mjs +0 -21
- package/dist/packem_shared/stableStringify-mC40mZts.mjs +0 -40
- package/dist/packem_shared/stableWireKey-DKuXO7T5.mjs +0 -6
- package/dist/packem_shared/subscriptionListDeltas-CT76bYny.mjs +0 -126
- package/dist/packem_shared/wire-codec-CzQc1pvf.mjs +0 -225
|
@@ -1,223 +0,0 @@
|
|
|
1
|
-
import { isLunoraError } from '@lunora/errors';
|
|
2
|
-
|
|
3
|
-
const stringifyFieldValue = (value) => {
|
|
4
|
-
if (typeof value === "string") {
|
|
5
|
-
return value;
|
|
6
|
-
}
|
|
7
|
-
try {
|
|
8
|
-
return JSON.stringify(value) ?? String(value);
|
|
9
|
-
} catch {
|
|
10
|
-
return String(value);
|
|
11
|
-
}
|
|
12
|
-
};
|
|
13
|
-
const coerceFieldValue = (value) => typeof value === "boolean" || typeof value === "number" || typeof value === "string" ? value : stringifyFieldValue(value);
|
|
14
|
-
const normalizeLogFields = (perCall, bound) => {
|
|
15
|
-
if (perCall === void 0 && bound === void 0) {
|
|
16
|
-
return void 0;
|
|
17
|
-
}
|
|
18
|
-
const merged = {};
|
|
19
|
-
if (bound !== void 0) {
|
|
20
|
-
for (const [key, value] of Object.entries(bound)) {
|
|
21
|
-
merged[key] = coerceFieldValue(value);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
if (perCall !== void 0) {
|
|
25
|
-
for (const [key, value] of Object.entries(perCall)) {
|
|
26
|
-
merged[key] = coerceFieldValue(value);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
return Object.keys(merged).length === 0 ? void 0 : merged;
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
const otlpRandomHex = (bytes) => {
|
|
33
|
-
const buffer = new Uint8Array(bytes);
|
|
34
|
-
crypto.getRandomValues(buffer);
|
|
35
|
-
let hex = "";
|
|
36
|
-
for (const byte of buffer) {
|
|
37
|
-
hex += byte.toString(16).padStart(2, "0");
|
|
38
|
-
}
|
|
39
|
-
return hex;
|
|
40
|
-
};
|
|
41
|
-
const HEX_ONLY = /^[0-9a-f]+$/;
|
|
42
|
-
const parseTraceparent = (header) => {
|
|
43
|
-
if (header === null || header === void 0) {
|
|
44
|
-
return void 0;
|
|
45
|
-
}
|
|
46
|
-
const parts = header.trim().toLowerCase().split("-");
|
|
47
|
-
const [version, traceId, parentSpanId, flags] = parts;
|
|
48
|
-
if (parts.length < 4 || version === void 0 || version.length !== 2 || !HEX_ONLY.test(version) || version === "ff" || // Version 00 forbids trailing fields; only a future version may carry them.
|
|
49
|
-
version === "00" && parts.length !== 4 || traceId === void 0 || parentSpanId === void 0 || flags === void 0 || flags.length !== 2 || !HEX_ONLY.test(flags) || traceId.length !== 32 || parentSpanId.length !== 16 || !HEX_ONLY.test(traceId) || !HEX_ONLY.test(parentSpanId) || traceId === "00000000000000000000000000000000" || parentSpanId === "0000000000000000") {
|
|
50
|
-
return void 0;
|
|
51
|
-
}
|
|
52
|
-
return { parentSpanId, sampled: (Number.parseInt(flags, 16) & 1) === 1, traceId };
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
const resolveTraceAnchor = (traceparent) => {
|
|
56
|
-
const inbound = parseTraceparent(traceparent);
|
|
57
|
-
return { rootSpanId: inbound?.parentSpanId ?? otlpRandomHex(8), traceId: inbound?.traceId ?? otlpRandomHex(16) };
|
|
58
|
-
};
|
|
59
|
-
const toErrorType = (error) => {
|
|
60
|
-
if (isLunoraError(error)) {
|
|
61
|
-
return error.code;
|
|
62
|
-
}
|
|
63
|
-
return error instanceof Error ? error.constructor.name : "Error";
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
const applyCloudflareSpanAttributes = (span, meta) => {
|
|
67
|
-
if (!span.isTraced) {
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
span.setAttribute("lunora.function_path", meta.functionPath);
|
|
71
|
-
span.setAttribute("lunora.ok", meta.ok);
|
|
72
|
-
span.setAttribute("lunora.duration_ms", meta.durationMs);
|
|
73
|
-
if (meta.shardKey !== void 0) {
|
|
74
|
-
span.setAttribute("lunora.shard_key", meta.shardKey);
|
|
75
|
-
}
|
|
76
|
-
if (meta.userId !== void 0) {
|
|
77
|
-
span.setAttribute("lunora.user_id", meta.userId);
|
|
78
|
-
}
|
|
79
|
-
if (meta.error !== void 0) {
|
|
80
|
-
span.setAttribute("lunora.error.type", meta.error.type);
|
|
81
|
-
span.setAttribute("lunora.error.message", meta.error.message);
|
|
82
|
-
}
|
|
83
|
-
for (const [key, value] of Object.entries(meta.attributes)) {
|
|
84
|
-
if (typeof value === "boolean" || typeof value === "number" || typeof value === "string") {
|
|
85
|
-
span.setAttribute(`lunora.attr.${key}`, value);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
};
|
|
89
|
-
const createTracer = (deps) => {
|
|
90
|
-
const { anchor, fuseCloudflareSpans, functionPath, record, resolveCloudflareTracing, shardKey, userId } = deps;
|
|
91
|
-
const tracerFor = (parentSpanId) => async (name, function_, attributes) => {
|
|
92
|
-
const spanId = otlpRandomHex(8);
|
|
93
|
-
const startTs = Date.now();
|
|
94
|
-
const normalized = normalizeLogFields(attributes);
|
|
95
|
-
const collected = {};
|
|
96
|
-
const spanHandle = {
|
|
97
|
-
setAttribute: (key, value) => {
|
|
98
|
-
Object.assign(collected, normalizeLogFields({ [key]: value }));
|
|
99
|
-
},
|
|
100
|
-
setAttributes: (fields) => {
|
|
101
|
-
Object.assign(collected, normalizeLogFields(fields));
|
|
102
|
-
}
|
|
103
|
-
};
|
|
104
|
-
const runRecorded = async (cfSpan) => {
|
|
105
|
-
let ok = true;
|
|
106
|
-
let error;
|
|
107
|
-
try {
|
|
108
|
-
return await function_(tracerFor(spanId), spanHandle);
|
|
109
|
-
} catch (error_) {
|
|
110
|
-
ok = false;
|
|
111
|
-
error = {
|
|
112
|
-
message: error_ instanceof Error ? error_.message : String(error_),
|
|
113
|
-
// Prefer a LunoraError's stable `code` over the class name
|
|
114
|
-
// so spans group by the same taxonomy the RPC spans use.
|
|
115
|
-
type: toErrorType(error_)
|
|
116
|
-
};
|
|
117
|
-
throw error_;
|
|
118
|
-
} finally {
|
|
119
|
-
const durationMs = Date.now() - startTs;
|
|
120
|
-
const resolvedUserId = userId();
|
|
121
|
-
const merged = { ...normalized, ...collected };
|
|
122
|
-
try {
|
|
123
|
-
record({
|
|
124
|
-
...Object.keys(merged).length === 0 ? {} : { attributes: merged },
|
|
125
|
-
durationMs,
|
|
126
|
-
...error === void 0 ? {} : { error },
|
|
127
|
-
functionPath,
|
|
128
|
-
name,
|
|
129
|
-
ok,
|
|
130
|
-
parentSpanId,
|
|
131
|
-
shardKey,
|
|
132
|
-
spanId,
|
|
133
|
-
startTs,
|
|
134
|
-
traceId: anchor.traceId,
|
|
135
|
-
userId: resolvedUserId
|
|
136
|
-
});
|
|
137
|
-
} catch {
|
|
138
|
-
}
|
|
139
|
-
if (cfSpan !== void 0) {
|
|
140
|
-
try {
|
|
141
|
-
applyCloudflareSpanAttributes(cfSpan, {
|
|
142
|
-
attributes: merged,
|
|
143
|
-
durationMs,
|
|
144
|
-
error,
|
|
145
|
-
functionPath,
|
|
146
|
-
ok,
|
|
147
|
-
shardKey,
|
|
148
|
-
userId: resolvedUserId
|
|
149
|
-
});
|
|
150
|
-
} catch {
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
};
|
|
155
|
-
if (fuseCloudflareSpans === true && resolveCloudflareTracing !== void 0) {
|
|
156
|
-
const cfTracing = await resolveCloudflareTracing();
|
|
157
|
-
if (cfTracing !== void 0 && typeof cfTracing.enterSpan === "function") {
|
|
158
|
-
return await cfTracing.enterSpan(name, (span) => runRecorded(span));
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
return await runRecorded();
|
|
162
|
-
};
|
|
163
|
-
return tracerFor(anchor.rootSpanId);
|
|
164
|
-
};
|
|
165
|
-
const createMetrics = (deps) => {
|
|
166
|
-
const { functionPath, record, shardKey } = deps;
|
|
167
|
-
const emit = (kind, name, value, attributes) => {
|
|
168
|
-
if (!Number.isFinite(value)) {
|
|
169
|
-
return;
|
|
170
|
-
}
|
|
171
|
-
const normalized = normalizeLogFields(attributes);
|
|
172
|
-
try {
|
|
173
|
-
record({
|
|
174
|
-
...normalized === void 0 ? {} : { attributes: normalized },
|
|
175
|
-
functionPath,
|
|
176
|
-
kind,
|
|
177
|
-
name,
|
|
178
|
-
shardKey,
|
|
179
|
-
ts: Date.now(),
|
|
180
|
-
value
|
|
181
|
-
});
|
|
182
|
-
} catch {
|
|
183
|
-
}
|
|
184
|
-
};
|
|
185
|
-
return {
|
|
186
|
-
count: (name, value = 1, attributes) => {
|
|
187
|
-
emit("counter", name, value, attributes);
|
|
188
|
-
},
|
|
189
|
-
gauge: (name, value, attributes) => {
|
|
190
|
-
emit("gauge", name, value, attributes);
|
|
191
|
-
},
|
|
192
|
-
record: (name, value, attributes) => {
|
|
193
|
-
emit("histogram", name, value, attributes);
|
|
194
|
-
}
|
|
195
|
-
};
|
|
196
|
-
};
|
|
197
|
-
const dispatchRootSpan = (input) => {
|
|
198
|
-
const { anchor, durationMs, failure, functionPath, shardKey, startTs, userId } = input;
|
|
199
|
-
return {
|
|
200
|
-
dispatch: true,
|
|
201
|
-
durationMs,
|
|
202
|
-
...failure === void 0 ? {} : {
|
|
203
|
-
error: {
|
|
204
|
-
message: failure.thrown instanceof Error ? failure.thrown.message : String(failure.thrown),
|
|
205
|
-
type: toErrorType(failure.thrown)
|
|
206
|
-
}
|
|
207
|
-
},
|
|
208
|
-
functionPath,
|
|
209
|
-
name: functionPath,
|
|
210
|
-
ok: failure === void 0,
|
|
211
|
-
// Empty: this span IS the trace's root locally. The worker's own RPC span
|
|
212
|
-
// sits above it in a full collector-side trace, but it is not in this
|
|
213
|
-
// buffer, so naming it here would dangle.
|
|
214
|
-
parentSpanId: "",
|
|
215
|
-
shardKey,
|
|
216
|
-
spanId: anchor.rootSpanId,
|
|
217
|
-
startTs,
|
|
218
|
-
traceId: anchor.traceId,
|
|
219
|
-
userId
|
|
220
|
-
};
|
|
221
|
-
};
|
|
222
|
-
|
|
223
|
-
export { createTracer as a, applyCloudflareSpanAttributes as b, createMetrics as c, dispatchRootSpan as d, normalizeLogFields as n, parseTraceparent as p, resolveTraceAnchor as r };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { b as applyCloudflareSpanAttributes, c as createMetrics, a as createTracer, d as dispatchRootSpan } from './context-telemetry-CDpyil58.mjs';
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { LunoraError } from '@lunora/errors';
|
|
2
|
-
|
|
3
|
-
const toScheduledFunctionDoc = (record) => {
|
|
4
|
-
const doc = {
|
|
5
|
-
args: record["args"] ?? {},
|
|
6
|
-
enqueuedAt: typeof record["enqueuedAt"] === "number" ? record["enqueuedAt"] : 0,
|
|
7
|
-
functionPath: typeof record["functionPath"] === "string" ? record["functionPath"] : "",
|
|
8
|
-
id: typeof record["id"] === "string" ? record["id"] : "",
|
|
9
|
-
scheduledFor: typeof record["scheduledFor"] === "number" ? record["scheduledFor"] : 0
|
|
10
|
-
};
|
|
11
|
-
if (typeof record["attempts"] === "number") {
|
|
12
|
-
doc.attempts = record["attempts"];
|
|
13
|
-
}
|
|
14
|
-
if (typeof record["shardKey"] === "string") {
|
|
15
|
-
doc.shardKey = record["shardKey"];
|
|
16
|
-
}
|
|
17
|
-
return doc;
|
|
18
|
-
};
|
|
19
|
-
const toStorageMetadata = (object) => {
|
|
20
|
-
const meta = {
|
|
21
|
-
key: typeof object["key"] === "string" ? object["key"] : "",
|
|
22
|
-
size: typeof object["size"] === "number" ? object["size"] : 0
|
|
23
|
-
};
|
|
24
|
-
const contentType = object["httpMetadata"]?.contentType ?? object["contentType"];
|
|
25
|
-
if (typeof contentType === "string") {
|
|
26
|
-
meta.contentType = contentType;
|
|
27
|
-
}
|
|
28
|
-
if (object["customMetadata"] && typeof object["customMetadata"] === "object") {
|
|
29
|
-
meta.customMetadata = object["customMetadata"];
|
|
30
|
-
}
|
|
31
|
-
if (typeof object["sha256"] === "string") {
|
|
32
|
-
meta.sha256 = object["sha256"];
|
|
33
|
-
}
|
|
34
|
-
const { uploaded } = object;
|
|
35
|
-
if (typeof uploaded === "number") {
|
|
36
|
-
meta.uploaded = uploaded;
|
|
37
|
-
} else if (uploaded instanceof Date) {
|
|
38
|
-
meta.uploaded = uploaded.getTime();
|
|
39
|
-
}
|
|
40
|
-
return meta;
|
|
41
|
-
};
|
|
42
|
-
const createSystemReader = (options = {}) => {
|
|
43
|
-
const requireScheduler = () => {
|
|
44
|
-
if (!options.scheduler) {
|
|
45
|
-
throw new LunoraError("INTERNAL", 'ctx.db.system.query("_scheduled_functions"): no scheduler configured. Pass `scheduler` to createShardDO().');
|
|
46
|
-
}
|
|
47
|
-
return options.scheduler;
|
|
48
|
-
};
|
|
49
|
-
const requireStorage = () => {
|
|
50
|
-
if (!options.storage) {
|
|
51
|
-
throw new LunoraError("INTERNAL", 'ctx.db.system.query("_storage"): no storage configured. Pass `storage` to createShardDO().');
|
|
52
|
-
}
|
|
53
|
-
return options.storage;
|
|
54
|
-
};
|
|
55
|
-
const collectScheduled = async () => {
|
|
56
|
-
const records = await requireScheduler().list();
|
|
57
|
-
return records.map((record) => toScheduledFunctionDoc(record));
|
|
58
|
-
};
|
|
59
|
-
const collectStorage = async () => {
|
|
60
|
-
const { objects } = await requireStorage().list();
|
|
61
|
-
return objects.map((object) => toStorageMetadata(object));
|
|
62
|
-
};
|
|
63
|
-
const queryReader = ((table) => {
|
|
64
|
-
if (table === "_scheduled_functions") {
|
|
65
|
-
return { collect: collectScheduled };
|
|
66
|
-
}
|
|
67
|
-
return { collect: collectStorage };
|
|
68
|
-
});
|
|
69
|
-
return {
|
|
70
|
-
get: (async (table, id) => {
|
|
71
|
-
if (table === "_scheduled_functions") {
|
|
72
|
-
const record = await requireScheduler().get(id);
|
|
73
|
-
return record ? toScheduledFunctionDoc(record) : null;
|
|
74
|
-
}
|
|
75
|
-
const meta = await requireStorage().getMetadata(id);
|
|
76
|
-
return meta ? toStorageMetadata(meta) : null;
|
|
77
|
-
}),
|
|
78
|
-
query: queryReader
|
|
79
|
-
};
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
export { createSystemReader };
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import { sql } from 'drizzle-orm';
|
|
2
|
-
import { r as runDrizzle } from './do-exec-5eQy5cEi.mjs';
|
|
3
|
-
|
|
4
|
-
const CLIENT_WATERMARK_TABLE = "__client_watermark";
|
|
5
|
-
const migrateClientWatermark = (sql$1) => {
|
|
6
|
-
runDrizzle(
|
|
7
|
-
sql$1,
|
|
8
|
-
sql`CREATE TABLE IF NOT EXISTS ${sql.identifier(CLIENT_WATERMARK_TABLE)} (
|
|
9
|
-
identity TEXT NOT NULL,
|
|
10
|
-
client_id TEXT NOT NULL,
|
|
11
|
-
last_mutation_id INTEGER NOT NULL,
|
|
12
|
-
PRIMARY KEY (identity, client_id)
|
|
13
|
-
)`
|
|
14
|
-
);
|
|
15
|
-
};
|
|
16
|
-
const readClientWatermark = (sql$1, identity, clientId) => {
|
|
17
|
-
const rows = runDrizzle(
|
|
18
|
-
sql$1,
|
|
19
|
-
sql`SELECT last_mutation_id FROM ${sql.identifier(CLIENT_WATERMARK_TABLE)} WHERE identity = ${identity} AND client_id = ${clientId} LIMIT 1`
|
|
20
|
-
).toArray();
|
|
21
|
-
return rows[0]?.last_mutation_id ?? 0;
|
|
22
|
-
};
|
|
23
|
-
const advanceClientWatermark = (sql$1, identity, clientId, mutationId) => {
|
|
24
|
-
runDrizzle(
|
|
25
|
-
sql$1,
|
|
26
|
-
sql`INSERT INTO ${sql.identifier(CLIENT_WATERMARK_TABLE)} (identity, client_id, last_mutation_id) VALUES (${identity}, ${clientId}, ${mutationId})
|
|
27
|
-
ON CONFLICT(identity, client_id) DO UPDATE SET last_mutation_id = MAX(last_mutation_id, excluded.last_mutation_id)`
|
|
28
|
-
);
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
const GLOBAL_SHAPE_SNAPSHOT_TABLE = "__global_shape_snapshot";
|
|
32
|
-
const migrateGlobalShapeSnapshot = (sql$1) => {
|
|
33
|
-
runDrizzle(
|
|
34
|
-
sql$1,
|
|
35
|
-
sql`CREATE TABLE IF NOT EXISTS ${sql.identifier(GLOBAL_SHAPE_SNAPSHOT_TABLE)} (
|
|
36
|
-
connection_id TEXT NOT NULL,
|
|
37
|
-
sub_id TEXT NOT NULL,
|
|
38
|
-
members TEXT NOT NULL,
|
|
39
|
-
PRIMARY KEY (connection_id, sub_id)
|
|
40
|
-
)`
|
|
41
|
-
);
|
|
42
|
-
};
|
|
43
|
-
const readGlobalShapeSnapshot = (sql$1, connectionId, subId) => {
|
|
44
|
-
const rows = runDrizzle(
|
|
45
|
-
sql$1,
|
|
46
|
-
sql`SELECT members FROM ${sql.identifier(GLOBAL_SHAPE_SNAPSHOT_TABLE)} WHERE connection_id = ${connectionId} AND sub_id = ${subId} LIMIT 1`
|
|
47
|
-
).toArray();
|
|
48
|
-
const raw = rows[0]?.members;
|
|
49
|
-
if (raw === void 0) {
|
|
50
|
-
return /* @__PURE__ */ new Map();
|
|
51
|
-
}
|
|
52
|
-
try {
|
|
53
|
-
const parsed = JSON.parse(raw);
|
|
54
|
-
if (parsed === null || typeof parsed !== "object") {
|
|
55
|
-
return /* @__PURE__ */ new Map();
|
|
56
|
-
}
|
|
57
|
-
return new Map(Object.entries(parsed));
|
|
58
|
-
} catch {
|
|
59
|
-
return /* @__PURE__ */ new Map();
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
const writeGlobalShapeSnapshot = (sql$1, connectionId, subId, snapshot) => {
|
|
63
|
-
const members = JSON.stringify(Object.fromEntries(snapshot));
|
|
64
|
-
runDrizzle(
|
|
65
|
-
sql$1,
|
|
66
|
-
sql`INSERT INTO ${sql.identifier(GLOBAL_SHAPE_SNAPSHOT_TABLE)} (connection_id, sub_id, members) VALUES (${connectionId}, ${subId}, ${members})
|
|
67
|
-
ON CONFLICT(connection_id, sub_id) DO UPDATE SET members = excluded.members`
|
|
68
|
-
);
|
|
69
|
-
};
|
|
70
|
-
const deleteGlobalShapeSnapshot = (sql$1, connectionId, subId) => {
|
|
71
|
-
runDrizzle(sql$1, sql`DELETE FROM ${sql.identifier(GLOBAL_SHAPE_SNAPSHOT_TABLE)} WHERE connection_id = ${connectionId} AND sub_id = ${subId}`);
|
|
72
|
-
};
|
|
73
|
-
const deleteGlobalShapeSnapshotsForConnection = (sql$1, connectionId) => {
|
|
74
|
-
runDrizzle(sql$1, sql`DELETE FROM ${sql.identifier(GLOBAL_SHAPE_SNAPSHOT_TABLE)} WHERE connection_id = ${connectionId}`);
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
const IDEMPOTENCY_TABLE = "__idempotency";
|
|
78
|
-
const migrateIdempotency = (sql$1) => {
|
|
79
|
-
runDrizzle(
|
|
80
|
-
sql$1,
|
|
81
|
-
sql`CREATE TABLE IF NOT EXISTS ${sql.identifier(IDEMPOTENCY_TABLE)} (
|
|
82
|
-
identity TEXT NOT NULL,
|
|
83
|
-
mutation_id TEXT NOT NULL,
|
|
84
|
-
result_json TEXT NOT NULL,
|
|
85
|
-
ts REAL NOT NULL,
|
|
86
|
-
PRIMARY KEY (identity, mutation_id)
|
|
87
|
-
)`
|
|
88
|
-
);
|
|
89
|
-
};
|
|
90
|
-
const readIdempotent = (sql$1, identity, mutationId) => {
|
|
91
|
-
const rows = runDrizzle(
|
|
92
|
-
sql$1,
|
|
93
|
-
sql`SELECT result_json, ts FROM ${sql.identifier(IDEMPOTENCY_TABLE)} WHERE identity = ${identity} AND mutation_id = ${mutationId} LIMIT 1`
|
|
94
|
-
).toArray();
|
|
95
|
-
const row = rows[0];
|
|
96
|
-
return row === void 0 ? void 0 : { resultJson: row.result_json, ts: row.ts };
|
|
97
|
-
};
|
|
98
|
-
const writeIdempotent = (sql$1, identity, mutationId, resultJson, ts) => {
|
|
99
|
-
runDrizzle(
|
|
100
|
-
sql$1,
|
|
101
|
-
sql`INSERT OR IGNORE INTO ${sql.identifier(IDEMPOTENCY_TABLE)} (identity, mutation_id, result_json, ts) VALUES (${identity}, ${mutationId}, ${resultJson}, ${ts})`
|
|
102
|
-
);
|
|
103
|
-
};
|
|
104
|
-
const trimIdempotent = (sql$1, olderThanTs) => {
|
|
105
|
-
runDrizzle(sql$1, sql`DELETE FROM ${sql.identifier(IDEMPOTENCY_TABLE)} WHERE ts < ${olderThanTs}`);
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
export { CLIENT_WATERMARK_TABLE as C, GLOBAL_SHAPE_SNAPSHOT_TABLE as G, IDEMPOTENCY_TABLE as I, migrateIdempotency as a, migrateGlobalShapeSnapshot as b, advanceClientWatermark as c, deleteGlobalShapeSnapshot as d, deleteGlobalShapeSnapshotsForConnection as e, readGlobalShapeSnapshot as f, readIdempotent as g, writeIdempotent as h, migrateClientWatermark as m, readClientWatermark as r, trimIdempotent as t, writeGlobalShapeSnapshot as w };
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { sql } from 'drizzle-orm';
|
|
2
|
-
import { r as runDrizzle } from './do-exec-5eQy5cEi.mjs';
|
|
3
|
-
import { D as DOC_COLUMN, r as rowToDocument, j as jsonPathSql } from './do-sql-CGAgiQUz.mjs';
|
|
4
|
-
import { compileWhereSql } from './compileWhereSql-DE6yfRcQ.mjs';
|
|
5
|
-
import { s as serializeSqlValue } from './serialize-sql-BlRUoiQe.mjs';
|
|
6
|
-
|
|
7
|
-
const shapeWhereStrategy = { fieldRef: jsonPathSql, serialize: serializeSqlValue };
|
|
8
|
-
const idInClause = (ids) => {
|
|
9
|
-
if (ids.length === 0) {
|
|
10
|
-
return void 0;
|
|
11
|
-
}
|
|
12
|
-
return sql`id IN (${sql.join(
|
|
13
|
-
ids.map((id) => sql`${id}`),
|
|
14
|
-
sql`, `
|
|
15
|
-
)})`;
|
|
16
|
-
};
|
|
17
|
-
const composeWhere = (effectiveWhere, idRestriction) => {
|
|
18
|
-
const conditions = [];
|
|
19
|
-
if (idRestriction) {
|
|
20
|
-
conditions.push(idRestriction);
|
|
21
|
-
}
|
|
22
|
-
const compiled = compileWhereSql(effectiveWhere, shapeWhereStrategy);
|
|
23
|
-
if (compiled) {
|
|
24
|
-
conditions.push(compiled);
|
|
25
|
-
}
|
|
26
|
-
if (conditions.length === 0) {
|
|
27
|
-
return sql``;
|
|
28
|
-
}
|
|
29
|
-
return sql` WHERE ${sql.join(conditions, sql` AND `)}`;
|
|
30
|
-
};
|
|
31
|
-
const selectShapeRows = (sql$1, table, effectiveWhere) => {
|
|
32
|
-
const whereClause = composeWhere(effectiveWhere, void 0);
|
|
33
|
-
const rows = runDrizzle(sql$1, sql`SELECT id, _creationTime, ${sql.identifier(DOC_COLUMN)} FROM ${sql.identifier(table)}${whereClause}`).toArray();
|
|
34
|
-
const result = [];
|
|
35
|
-
for (const row of rows) {
|
|
36
|
-
const doc = rowToDocument(row);
|
|
37
|
-
const { id } = row;
|
|
38
|
-
if (doc !== void 0 && typeof id === "string") {
|
|
39
|
-
result.push({ doc, id });
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
return result;
|
|
43
|
-
};
|
|
44
|
-
const selectShapeMemberIds = (sql$1, table, effectiveWhere, ids) => {
|
|
45
|
-
if (ids.length === 0) {
|
|
46
|
-
return /* @__PURE__ */ new Set();
|
|
47
|
-
}
|
|
48
|
-
const whereClause = composeWhere(effectiveWhere, idInClause(ids));
|
|
49
|
-
const rows = runDrizzle(sql$1, sql`SELECT id FROM ${sql.identifier(table)}${whereClause}`).toArray();
|
|
50
|
-
return new Set(rows.map((row) => row.id));
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
export { selectShapeMemberIds as a, selectShapeRows as s };
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { stableStringify } from './stableStringify-mC40mZts.mjs';
|
|
2
|
-
|
|
3
|
-
const projectExternalSourceRow = (row, columns) => {
|
|
4
|
-
const projected = { _id: row._id };
|
|
5
|
-
if (columns) {
|
|
6
|
-
for (const key of columns) {
|
|
7
|
-
if (Object.hasOwn(row, key)) {
|
|
8
|
-
projected[key] = row[key];
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
return projected;
|
|
12
|
-
}
|
|
13
|
-
for (const [key, value] of Object.entries(row)) {
|
|
14
|
-
if (key !== "_id" && key !== "_creationTime") {
|
|
15
|
-
projected[key] = value;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
return projected;
|
|
19
|
-
};
|
|
20
|
-
const diffExternalSource = (pulled, baseline, options) => {
|
|
21
|
-
const { columns, table } = options;
|
|
22
|
-
const changes = [];
|
|
23
|
-
const nextBaseline = /* @__PURE__ */ new Map();
|
|
24
|
-
for (const source of pulled) {
|
|
25
|
-
const value = projectExternalSourceRow(source, columns);
|
|
26
|
-
const id = String(value._id);
|
|
27
|
-
const json = stableStringify(value);
|
|
28
|
-
nextBaseline.set(id, json);
|
|
29
|
-
const before = baseline.get(id);
|
|
30
|
-
if (before === void 0) {
|
|
31
|
-
changes.push({ doc: value, id, op: "insert", seq: 0, table, ts: 0 });
|
|
32
|
-
} else if (before !== json) {
|
|
33
|
-
changes.push({ doc: value, id, op: "update", seq: 0, table, ts: 0 });
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
for (const id of baseline.keys()) {
|
|
37
|
-
if (!nextBaseline.has(id)) {
|
|
38
|
-
changes.push({ id, op: "delete", seq: 0, table, ts: 0 });
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
return { changes, nextBaseline };
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
export { diffExternalSource, projectExternalSourceRow };
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { renderSql } from './renderSql-D6eUcn2N.mjs';
|
|
2
|
-
|
|
3
|
-
const runSql = (sql, query, ...params) => {
|
|
4
|
-
const runner = sql.exec;
|
|
5
|
-
return runner.call(sql, query, ...params);
|
|
6
|
-
};
|
|
7
|
-
const runDrizzle = (exec, query) => {
|
|
8
|
-
const { params, sql: text } = renderSql("sqlite", query);
|
|
9
|
-
return runSql(exec, text, ...params);
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
export { runDrizzle as r };
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import { sql } from 'drizzle-orm';
|
|
2
|
-
import { r as runDrizzle } from './do-exec-5eQy5cEi.mjs';
|
|
3
|
-
|
|
4
|
-
const DOC_COLUMN = "__doc__";
|
|
5
|
-
const geoTableName = (table, indexName) => `${table}__geo_${indexName}`;
|
|
6
|
-
const quoteIdentifier = (name) => `"${name.replaceAll('"', '""')}"`;
|
|
7
|
-
const jsonPath = (field) => {
|
|
8
|
-
if (field === "_id" || field === "id") {
|
|
9
|
-
return "id";
|
|
10
|
-
}
|
|
11
|
-
if (field === "_creationTime") {
|
|
12
|
-
return "_creationTime";
|
|
13
|
-
}
|
|
14
|
-
return `json_extract(${DOC_COLUMN}, '$.${field.replaceAll("'", "''")}')`;
|
|
15
|
-
};
|
|
16
|
-
const jsonPathSql = (field) => sql.raw(jsonPath(field));
|
|
17
|
-
const qualifiedJsonPath = (table, field) => {
|
|
18
|
-
const qualified = quoteIdentifier(table);
|
|
19
|
-
if (field === "_id" || field === "id") {
|
|
20
|
-
return `${qualified}.id`;
|
|
21
|
-
}
|
|
22
|
-
if (field === "_creationTime") {
|
|
23
|
-
return `${qualified}._creationTime`;
|
|
24
|
-
}
|
|
25
|
-
return `json_extract(${qualified}.${DOC_COLUMN}, '$.${field.replaceAll("'", "''")}')`;
|
|
26
|
-
};
|
|
27
|
-
const qualifiedJsonPathSql = (table, field) => sql.raw(qualifiedJsonPath(table, field));
|
|
28
|
-
const createIndexSql = (name, table, columns, unique) => sql`CREATE ${unique ? sql`UNIQUE ` : sql``}INDEX IF NOT EXISTS ${sql.identifier(name)} ON ${sql.identifier(table)} (${columns})`;
|
|
29
|
-
const AGG_KEY = sql.identifier("__key__");
|
|
30
|
-
const AGG_VALUE = sql.identifier("__value__");
|
|
31
|
-
const AGG_COUNT = sql.identifier("__count__");
|
|
32
|
-
const aggUpsertSql = (aggTable, key, value, count, set) => sql`INSERT INTO ${sql.identifier(aggTable)} (${AGG_KEY}, ${AGG_VALUE}, ${AGG_COUNT}) VALUES (${key}, ${value}, ${count}) ON CONFLICT(${AGG_KEY}) DO UPDATE SET ${set}`;
|
|
33
|
-
const tableColumns = (definition) => {
|
|
34
|
-
const columns = [];
|
|
35
|
-
for (const [field, validator] of Object.entries(definition.shape)) {
|
|
36
|
-
const column = validator._meta?.column;
|
|
37
|
-
if (column) {
|
|
38
|
-
columns.push([field, column]);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
return columns;
|
|
42
|
-
};
|
|
43
|
-
const rowToDocument = (row) => {
|
|
44
|
-
if (!row) {
|
|
45
|
-
return void 0;
|
|
46
|
-
}
|
|
47
|
-
const raw = row[DOC_COLUMN];
|
|
48
|
-
let parsed;
|
|
49
|
-
if (typeof raw === "string") {
|
|
50
|
-
parsed = JSON.parse(raw);
|
|
51
|
-
} else if (raw && typeof raw === "object") {
|
|
52
|
-
parsed = raw;
|
|
53
|
-
} else {
|
|
54
|
-
parsed = {};
|
|
55
|
-
}
|
|
56
|
-
const { id } = row;
|
|
57
|
-
if (typeof id === "string") {
|
|
58
|
-
parsed["_id"] = id;
|
|
59
|
-
}
|
|
60
|
-
const creationTime = row["_creationTime"];
|
|
61
|
-
if (typeof creationTime === "number") {
|
|
62
|
-
parsed["_creationTime"] = creationTime;
|
|
63
|
-
}
|
|
64
|
-
return parsed;
|
|
65
|
-
};
|
|
66
|
-
const ftsAvailabilityCache = /* @__PURE__ */ new WeakMap();
|
|
67
|
-
const isFtsAvailable = (sql$1) => {
|
|
68
|
-
const cached = ftsAvailabilityCache.get(sql$1);
|
|
69
|
-
if (cached !== void 0) {
|
|
70
|
-
return cached;
|
|
71
|
-
}
|
|
72
|
-
let available;
|
|
73
|
-
try {
|
|
74
|
-
runDrizzle(sql$1, sql`CREATE VIRTUAL TABLE IF NOT EXISTS ${sql.identifier("__lunora_fts_probe")} USING fts5(x)`);
|
|
75
|
-
available = true;
|
|
76
|
-
} catch {
|
|
77
|
-
available = false;
|
|
78
|
-
} finally {
|
|
79
|
-
try {
|
|
80
|
-
runDrizzle(sql$1, sql`DROP TABLE IF EXISTS ${sql.identifier("__lunora_fts_probe")}`);
|
|
81
|
-
} catch {
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
ftsAvailabilityCache.set(sql$1, available);
|
|
85
|
-
return available;
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
export { AGG_KEY as A, DOC_COLUMN as D, AGG_VALUE as a, AGG_COUNT as b, createIndexSql as c, aggUpsertSql as d, qualifiedJsonPathSql as e, geoTableName as g, isFtsAvailable as i, jsonPathSql as j, quoteIdentifier as q, rowToDocument as r, tableColumns as t };
|