@gscdump/cloudflare 0.17.2 → 0.17.4
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 +15 -1
- package/dist/index.mjs +45 -1
- package/package.json +3 -3
package/dist/index.d.mts
CHANGED
|
@@ -56,6 +56,20 @@ interface AnalyticsEngineHooks {
|
|
|
56
56
|
onR2Write?: (byteLength: number) => void;
|
|
57
57
|
}
|
|
58
58
|
declare function getAnalyticsEngine(env: AnalyticsEnv, db: any, hooks?: AnalyticsEngineHooks): ReturnType<typeof createStorageEngine> | null;
|
|
59
|
+
interface InflightDedupe<T> {
|
|
60
|
+
dedupe: (key: string, run: () => Promise<T>) => Promise<T>;
|
|
61
|
+
has: (key: string) => boolean;
|
|
62
|
+
clear: () => void;
|
|
63
|
+
}
|
|
64
|
+
declare function createInflightDedupe<T>(): InflightDedupe<T>;
|
|
65
|
+
interface HostedR2QueryKeyInput {
|
|
66
|
+
userId: string | number;
|
|
67
|
+
siteId: string;
|
|
68
|
+
state: unknown;
|
|
69
|
+
comparison?: unknown;
|
|
70
|
+
comparisonFilter?: string;
|
|
71
|
+
}
|
|
72
|
+
declare function getHostedR2QueryKey(input: HostedR2QueryKeyInput): string;
|
|
59
73
|
interface PresignOptions {
|
|
60
74
|
key: string;
|
|
61
75
|
bucket: string;
|
|
@@ -70,4 +84,4 @@ declare function signSizeHint(env: AnalyticsEnv, key: string, bytes: number): Pr
|
|
|
70
84
|
declare function verifySizeHint(env: AnalyticsEnv, key: string, bytes: number, providedHex: string): Promise<boolean>;
|
|
71
85
|
declare function createDucklingsCodec(_env: AnalyticsEnv): ParquetCodec;
|
|
72
86
|
declare function createDucklingsExecutor(env: AnalyticsEnv): QueryExecutor;
|
|
73
|
-
export { type AnalyticsEngineHooks, type AnalyticsEnv, type PresignOptions, type Row, createDucklingsCodec, createDucklingsExecutor, createR2Presigner, getAnalyticsEngine, getWasmDuckDBFactory, resetWasmDuckDB, signSizeHint, useAnalyticsEnv, verifySizeHint };
|
|
87
|
+
export { type AnalyticsEngineHooks, type AnalyticsEnv, type HostedR2QueryKeyInput, type InflightDedupe, type PresignOptions, type Row, createDucklingsCodec, createDucklingsExecutor, createInflightDedupe, createR2Presigner, getAnalyticsEngine, getHostedR2QueryKey, getWasmDuckDBFactory, resetWasmDuckDB, signSizeHint, useAnalyticsEnv, verifySizeHint };
|
package/dist/index.mjs
CHANGED
|
@@ -129,6 +129,50 @@ function useAnalyticsEnv(event) {
|
|
|
129
129
|
statusMessage: "AnalyticsEnv not available — host must populate event.context.analyticsEnv or use the Cloudflare adapter"
|
|
130
130
|
});
|
|
131
131
|
}
|
|
132
|
+
function createInflightDedupe() {
|
|
133
|
+
const inflight = /* @__PURE__ */ new Map();
|
|
134
|
+
return {
|
|
135
|
+
dedupe(key, run) {
|
|
136
|
+
const existing = inflight.get(key);
|
|
137
|
+
if (existing) return existing;
|
|
138
|
+
const promise = run().finally(() => {
|
|
139
|
+
if (inflight.get(key) === promise) inflight.delete(key);
|
|
140
|
+
});
|
|
141
|
+
inflight.set(key, promise);
|
|
142
|
+
return promise;
|
|
143
|
+
},
|
|
144
|
+
has(key) {
|
|
145
|
+
return inflight.has(key);
|
|
146
|
+
},
|
|
147
|
+
clear() {
|
|
148
|
+
inflight.clear();
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
function stableStringify(value) {
|
|
153
|
+
if (Array.isArray(value)) return `[${value.map(stableStringify).join(",")}]`;
|
|
154
|
+
if (value && typeof value === "object") return `{${Object.keys(value).sort().map((key) => {
|
|
155
|
+
return `${JSON.stringify(key)}:${stableStringify(value[key])}`;
|
|
156
|
+
}).join(",")}}`;
|
|
157
|
+
return JSON.stringify(value);
|
|
158
|
+
}
|
|
159
|
+
function hashString(value) {
|
|
160
|
+
let hash = 0;
|
|
161
|
+
for (let i = 0; i < value.length; i++) {
|
|
162
|
+
hash = (hash << 5) - hash + value.charCodeAt(i);
|
|
163
|
+
hash |= 0;
|
|
164
|
+
}
|
|
165
|
+
return Math.abs(hash).toString(36);
|
|
166
|
+
}
|
|
167
|
+
function getHostedR2QueryKey(input) {
|
|
168
|
+
return [
|
|
169
|
+
input.userId,
|
|
170
|
+
input.siteId,
|
|
171
|
+
hashString(stableStringify(input.state)),
|
|
172
|
+
input.comparison ? hashString(stableStringify(input.comparison)) : "",
|
|
173
|
+
input.comparisonFilter ?? ""
|
|
174
|
+
].join(":");
|
|
175
|
+
}
|
|
132
176
|
function createR2Presigner(env) {
|
|
133
177
|
if (!env.R2_ACCESS_KEY_ID || !env.R2_SECRET_ACCESS_KEY) throw createError({
|
|
134
178
|
statusCode: 500,
|
|
@@ -197,4 +241,4 @@ async function verifySizeHint(env, key, bytes, providedHex) {
|
|
|
197
241
|
for (let i = 0; i < SIG_HEX_LEN; i++) diff |= expected.charCodeAt(i) ^ providedHex.charCodeAt(i);
|
|
198
242
|
return diff === 0;
|
|
199
243
|
}
|
|
200
|
-
export { createDucklingsCodec, createDucklingsExecutor, createR2Presigner, getAnalyticsEngine, getWasmDuckDBFactory, resetWasmDuckDB, signSizeHint, useAnalyticsEnv, verifySizeHint };
|
|
244
|
+
export { createDucklingsCodec, createDucklingsExecutor, createInflightDedupe, createR2Presigner, getAnalyticsEngine, getHostedR2QueryKey, getWasmDuckDBFactory, resetWasmDuckDB, signSizeHint, useAnalyticsEnv, verifySizeHint };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gscdump/cloudflare",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.17.
|
|
4
|
+
"version": "0.17.4",
|
|
5
5
|
"description": "Cloudflare-Workers-flavored helpers for the gscdump analytics stack: AnalyticsEnv binding contract, R2 SigV4 presigner, size-hint HMAC, DuckDB Workers shims, engine factory.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Harlan Wilton",
|
|
@@ -40,8 +40,8 @@
|
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"aws4fetch": "^1.0.20",
|
|
43
|
-
"@gscdump/engine-sqlite": "0.17.
|
|
44
|
-
"@gscdump/engine": "0.17.
|
|
43
|
+
"@gscdump/engine-sqlite": "0.17.4",
|
|
44
|
+
"@gscdump/engine": "0.17.4"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@cloudflare/workers-types": "^4.20260517.1",
|