@rocapine/rocalytics-sdk 0.0.0-stage → 0.3.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/CHANGELOG.md +86 -0
- package/LICENSE +21 -0
- package/README.md +449 -2
- package/client/package.json +1 -0
- package/core/package.json +4 -0
- package/dist/client/client.d.ts +146 -0
- package/dist/client/client.d.ts.map +1 -0
- package/dist/client/client.js +376 -0
- package/dist/client/client.js.map +1 -0
- package/dist/client/index.d.ts +13 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +35 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/native.d.ts +68 -0
- package/dist/client/native.d.ts.map +1 -0
- package/dist/client/native.js +64 -0
- package/dist/client/native.js.map +1 -0
- package/dist/client/onboardingSink.d.ts +63 -0
- package/dist/client/onboardingSink.d.ts.map +1 -0
- package/dist/client/onboardingSink.js +126 -0
- package/dist/client/onboardingSink.js.map +1 -0
- package/dist/client/paywallSink.d.ts +13 -0
- package/dist/client/paywallSink.d.ts.map +1 -0
- package/dist/client/paywallSink.js +26 -0
- package/dist/client/paywallSink.js.map +1 -0
- package/dist/client/requests.d.ts +66 -0
- package/dist/client/requests.d.ts.map +1 -0
- package/dist/client/requests.js +90 -0
- package/dist/client/requests.js.map +1 -0
- package/dist/client/types.d.ts +180 -0
- package/dist/client/types.d.ts.map +1 -0
- package/dist/client/types.js +4 -0
- package/dist/client/types.js.map +1 -0
- package/dist/core/context.d.ts +39 -0
- package/dist/core/context.d.ts.map +1 -0
- package/dist/core/context.js +45 -0
- package/dist/core/context.js.map +1 -0
- package/dist/core/delivery.d.ts +63 -0
- package/dist/core/delivery.d.ts.map +1 -0
- package/dist/core/delivery.js +133 -0
- package/dist/core/delivery.js.map +1 -0
- package/dist/core/diagnostics.d.ts +16 -0
- package/dist/core/diagnostics.d.ts.map +1 -0
- package/dist/core/diagnostics.js +24 -0
- package/dist/core/diagnostics.js.map +1 -0
- package/dist/core/httpSink.d.ts +35 -0
- package/dist/core/httpSink.d.ts.map +1 -0
- package/dist/core/httpSink.js +65 -0
- package/dist/core/httpSink.js.map +1 -0
- package/dist/core/ids.d.ts +16 -0
- package/dist/core/ids.d.ts.map +1 -0
- package/dist/core/ids.js +51 -0
- package/dist/core/ids.js.map +1 -0
- package/dist/core/index.d.ts +17 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +32 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/sink.d.ts +39 -0
- package/dist/core/sink.d.ts.map +1 -0
- package/dist/core/sink.js +16 -0
- package/dist/core/sink.js.map +1 -0
- package/dist/core/storage.d.ts +52 -0
- package/dist/core/storage.d.ts.map +1 -0
- package/dist/core/storage.js +79 -0
- package/dist/core/storage.js.map +1 -0
- package/dist/core/text.d.ts +9 -0
- package/dist/core/text.d.ts.map +1 -0
- package/dist/core/text.js +47 -0
- package/dist/core/text.js.map +1 -0
- package/dist/core/time.d.ts +18 -0
- package/dist/core/time.d.ts.map +1 -0
- package/dist/core/time.js +18 -0
- package/dist/core/time.js.map +1 -0
- package/dist/onboarding/contract.d.ts +138 -0
- package/dist/onboarding/contract.d.ts.map +1 -0
- package/dist/onboarding/contract.js +11 -0
- package/dist/onboarding/contract.js.map +1 -0
- package/dist/onboarding/index.d.ts +15 -0
- package/dist/onboarding/index.d.ts.map +1 -0
- package/dist/onboarding/index.js +22 -0
- package/dist/onboarding/index.js.map +1 -0
- package/dist/onboarding/input.d.ts +102 -0
- package/dist/onboarding/input.d.ts.map +1 -0
- package/dist/onboarding/input.js +216 -0
- package/dist/onboarding/input.js.map +1 -0
- package/dist/onboarding/persisted.d.ts +20 -0
- package/dist/onboarding/persisted.d.ts.map +1 -0
- package/dist/onboarding/persisted.js +75 -0
- package/dist/onboarding/persisted.js.map +1 -0
- package/dist/onboarding/state.d.ts +65 -0
- package/dist/onboarding/state.d.ts.map +1 -0
- package/dist/onboarding/state.js +207 -0
- package/dist/onboarding/state.js.map +1 -0
- package/dist/onboarding/tracker.d.ts +135 -0
- package/dist/onboarding/tracker.d.ts.map +1 -0
- package/dist/onboarding/tracker.js +734 -0
- package/dist/onboarding/tracker.js.map +1 -0
- package/dist/paywall/contract.d.ts +67 -0
- package/dist/paywall/contract.d.ts.map +1 -0
- package/dist/paywall/contract.js +3 -0
- package/dist/paywall/contract.js.map +1 -0
- package/dist/paywall/index.d.ts +14 -0
- package/dist/paywall/index.d.ts.map +1 -0
- package/dist/paywall/index.js +19 -0
- package/dist/paywall/index.js.map +1 -0
- package/dist/paywall/observer.d.ts +38 -0
- package/dist/paywall/observer.d.ts.map +1 -0
- package/dist/paywall/observer.js +6 -0
- package/dist/paywall/observer.js.map +1 -0
- package/dist/paywall/state.d.ts +26 -0
- package/dist/paywall/state.d.ts.map +1 -0
- package/dist/paywall/state.js +132 -0
- package/dist/paywall/state.js.map +1 -0
- package/dist/paywall/tracker.d.ts +36 -0
- package/dist/paywall/tracker.d.ts.map +1 -0
- package/dist/paywall/tracker.js +180 -0
- package/dist/paywall/tracker.js.map +1 -0
- package/dist/version.d.ts +3 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +6 -0
- package/dist/version.js.map +1 -0
- package/docs/onboarding-run-contract.md +1013 -0
- package/docs/onboarding-run.examples.ts +306 -0
- package/docs/onboarding-run.schema.json +224 -0
- package/docs/onboarding-run.types.ts +144 -0
- package/docs/paywall-presentation-contract.md +139 -0
- package/docs/paywall-presentation.examples.ts +42 -0
- package/docs/paywall-presentation.schema.json +268 -0
- package/docs/paywall-presentation.types.ts +73 -0
- package/onboarding/package.json +4 -0
- package/package.json +120 -4
- package/paywall/package.json +1 -0
- package/src/client/client.ts +417 -0
- package/src/client/index.ts +54 -0
- package/src/client/native.ts +109 -0
- package/src/client/onboardingSink.ts +121 -0
- package/src/client/paywallSink.ts +25 -0
- package/src/client/requests.ts +126 -0
- package/src/client/types.ts +198 -0
- package/src/core/context.ts +69 -0
- package/src/core/delivery.ts +181 -0
- package/src/core/diagnostics.ts +30 -0
- package/src/core/httpSink.ts +70 -0
- package/src/core/ids.ts +46 -0
- package/src/core/index.ts +20 -0
- package/src/core/sink.ts +46 -0
- package/src/core/storage.ts +112 -0
- package/src/core/text.ts +37 -0
- package/src/core/time.ts +26 -0
- package/src/onboarding/contract.ts +144 -0
- package/src/onboarding/index.ts +39 -0
- package/src/onboarding/input.ts +246 -0
- package/src/onboarding/persisted.ts +93 -0
- package/src/onboarding/state.ts +233 -0
- package/src/onboarding/tracker.ts +855 -0
- package/src/paywall/contract.ts +73 -0
- package/src/paywall/index.ts +36 -0
- package/src/paywall/observer.ts +43 -0
- package/src/paywall/state.ts +125 -0
- package/src/paywall/tracker.ts +200 -0
- package/src/version.ts +2 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createHttpSink = createHttpSink;
|
|
4
|
+
const sink_1 = require("./sink");
|
|
5
|
+
/**
|
|
6
|
+
* A sink that POSTs each payload to an HTTP collector.
|
|
7
|
+
*
|
|
8
|
+
* The outcome comes from the response BODY only: `{"outcome": "accepted" |
|
|
9
|
+
* "ignored" | "rejected"}`. The status code is not read, because a proxy or
|
|
10
|
+
* gateway can answer 401, 404 or 413 without having looked at the payload, so
|
|
11
|
+
* any response without an outcome, and no response at all, is transient.
|
|
12
|
+
* It never throws.
|
|
13
|
+
*
|
|
14
|
+
* Its `destination` is `url`, marked ` (custom fetch)` when a `fetch` is
|
|
15
|
+
* passed: that one may never reach `url` (a test double), so it never counts
|
|
16
|
+
* as the same destination as the real one. Headers are not part of it.
|
|
17
|
+
*/
|
|
18
|
+
function createHttpSink(options) {
|
|
19
|
+
var _a;
|
|
20
|
+
const timeoutMs = (_a = options.timeoutMs) !== null && _a !== void 0 ? _a : 15000;
|
|
21
|
+
return {
|
|
22
|
+
destination: options.fetch ? `${options.url} (custom fetch)` : options.url,
|
|
23
|
+
async send(payload) {
|
|
24
|
+
var _a;
|
|
25
|
+
const doFetch = (_a = options.fetch) !== null && _a !== void 0 ? _a : globalThis.fetch;
|
|
26
|
+
if (!doFetch)
|
|
27
|
+
return { outcome: "transient", reason: "no fetch available" };
|
|
28
|
+
const Abort = globalThis.AbortController;
|
|
29
|
+
const controller = Abort ? new Abort() : null;
|
|
30
|
+
let timer;
|
|
31
|
+
try {
|
|
32
|
+
const extra = typeof options.headers === "function" ? await options.headers() : options.headers;
|
|
33
|
+
const request = doFetch(options.url, {
|
|
34
|
+
method: "POST",
|
|
35
|
+
headers: { ...extra, "content-type": "application/json" },
|
|
36
|
+
body: JSON.stringify(payload),
|
|
37
|
+
signal: controller === null || controller === void 0 ? void 0 : controller.signal,
|
|
38
|
+
}).then((res) => res.text());
|
|
39
|
+
const timeout = new Promise((_, reject) => {
|
|
40
|
+
timer = setTimeout(() => {
|
|
41
|
+
controller === null || controller === void 0 ? void 0 : controller.abort();
|
|
42
|
+
reject(new Error("timeout"));
|
|
43
|
+
}, timeoutMs);
|
|
44
|
+
});
|
|
45
|
+
const text = await Promise.race([request, timeout]);
|
|
46
|
+
let body = undefined;
|
|
47
|
+
try {
|
|
48
|
+
body = JSON.parse(text);
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
// Not JSON: no outcome, so transient.
|
|
52
|
+
}
|
|
53
|
+
return (0, sink_1.normalizeResult)(body);
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
return { outcome: "transient", reason: String(error) };
|
|
57
|
+
}
|
|
58
|
+
finally {
|
|
59
|
+
if (timer !== undefined)
|
|
60
|
+
clearTimeout(timer);
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=httpSink.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"httpSink.js","sourceRoot":"","sources":["../../src/core/httpSink.ts"],"names":[],"mappings":";;AA8BA,wCAuCC;AArED,iCAAqE;AAiBrE;;;;;;;;;;;;GAYG;AACH,SAAgB,cAAc,CAAC,OAAwB;;IACrD,MAAM,SAAS,GAAG,MAAA,OAAO,CAAC,SAAS,mCAAI,KAAM,CAAC;IAC9C,OAAO;QACL,WAAW,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG;QAC1E,KAAK,CAAC,IAAI,CAAC,OAAO;;YAChB,MAAM,OAAO,GAAG,MAAA,OAAO,CAAC,KAAK,mCAAK,UAAU,CAAC,KAA6C,CAAC;YAC3F,IAAI,CAAC,OAAO;gBAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,oBAAoB,EAAE,CAAC;YAC5E,MAAM,KAAK,GAAI,UAAiF,CAAC,eAAe,CAAC;YACjH,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;YAC9C,IAAI,KAAgD,CAAC;YACrD,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,OAAO,OAAO,CAAC,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC;gBAChG,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE;oBACnC,MAAM,EAAE,MAAM;oBACd,OAAO,EAAE,EAAE,GAAG,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE;oBACzD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;oBAC7B,MAAM,EAAE,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,MAAM;iBAC3B,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;gBAC7B,MAAM,OAAO,GAAG,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE;oBAC/C,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;wBACtB,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,KAAK,EAAE,CAAC;wBACpB,MAAM,CAAC,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;oBAC/B,CAAC,EAAE,SAAS,CAAC,CAAC;gBAChB,CAAC,CAAC,CAAC;gBACH,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;gBACpD,IAAI,IAAI,GAAY,SAAS,CAAC;gBAC9B,IAAI,CAAC;oBACH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC1B,CAAC;gBAAC,MAAM,CAAC;oBACP,sCAAsC;gBACxC,CAAC;gBACD,OAAO,IAAA,sBAAe,EAAC,IAAI,CAAC,CAAC;YAC/B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YACzD,CAAC;oBAAS,CAAC;gBACT,IAAI,KAAK,KAAK,SAAS;oBAAE,YAAY,CAAC,KAAK,CAAC,CAAC;YAC/C,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Clock } from "./time";
|
|
2
|
+
/**
|
|
3
|
+
* A lowercase UUIDv7 (RFC 9562): 48 bits of millisecond time, then random
|
|
4
|
+
* bits. It sorts by creation time, which is why the contract recommends it.
|
|
5
|
+
* `random` must hold at least 16 bytes; only the bits after the time are used.
|
|
6
|
+
*/
|
|
7
|
+
export declare function uuidv7(nowMs: number, random: Uint8Array): string;
|
|
8
|
+
/**
|
|
9
|
+
* 16 random bytes from `crypto.getRandomValues` when the runtime has it, and
|
|
10
|
+
* from `Math.random` otherwise. A run id needs to be unique, not secret, so
|
|
11
|
+
* the fallback is acceptable on a runtime with no crypto global.
|
|
12
|
+
*/
|
|
13
|
+
export declare function randomBytes16(): Uint8Array;
|
|
14
|
+
/** The default id minter: UUIDv7 from the injected clock. */
|
|
15
|
+
export declare function createUuid(clock: Clock): () => string;
|
|
16
|
+
//# sourceMappingURL=ids.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ids.d.ts","sourceRoot":"","sources":["../../src/core/ids.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAQpC;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,MAAM,CAWhE;AAED;;;;GAIG;AACH,wBAAgB,aAAa,IAAI,UAAU,CAS1C;AAED,6DAA6D;AAC7D,wBAAgB,UAAU,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,MAAM,CAErD"}
|
package/dist/core/ids.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.uuidv7 = uuidv7;
|
|
4
|
+
exports.randomBytes16 = randomBytes16;
|
|
5
|
+
exports.createUuid = createUuid;
|
|
6
|
+
const hex = (bytes, from, to) => {
|
|
7
|
+
let out = "";
|
|
8
|
+
for (let i = from; i < to; i++)
|
|
9
|
+
out += (bytes[i] + 0x100).toString(16).slice(1);
|
|
10
|
+
return out;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* A lowercase UUIDv7 (RFC 9562): 48 bits of millisecond time, then random
|
|
14
|
+
* bits. It sorts by creation time, which is why the contract recommends it.
|
|
15
|
+
* `random` must hold at least 16 bytes; only the bits after the time are used.
|
|
16
|
+
*/
|
|
17
|
+
function uuidv7(nowMs, random) {
|
|
18
|
+
var _a;
|
|
19
|
+
const b = new Uint8Array(16);
|
|
20
|
+
for (let i = 0; i < 16; i++)
|
|
21
|
+
b[i] = (_a = random[i]) !== null && _a !== void 0 ? _a : 0;
|
|
22
|
+
let t = Math.max(0, Math.floor(nowMs));
|
|
23
|
+
for (let i = 5; i >= 0; i--) {
|
|
24
|
+
b[i] = t % 256;
|
|
25
|
+
t = Math.floor(t / 256);
|
|
26
|
+
}
|
|
27
|
+
b[6] = 0x70 | (b[6] & 0x0f); // version 7
|
|
28
|
+
b[8] = 0x80 | (b[8] & 0x3f); // variant 10xx
|
|
29
|
+
return `${hex(b, 0, 4)}-${hex(b, 4, 6)}-${hex(b, 6, 8)}-${hex(b, 8, 10)}-${hex(b, 10, 16)}`;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* 16 random bytes from `crypto.getRandomValues` when the runtime has it, and
|
|
33
|
+
* from `Math.random` otherwise. A run id needs to be unique, not secret, so
|
|
34
|
+
* the fallback is acceptable on a runtime with no crypto global.
|
|
35
|
+
*/
|
|
36
|
+
function randomBytes16() {
|
|
37
|
+
const out = new Uint8Array(16);
|
|
38
|
+
const c = globalThis.crypto;
|
|
39
|
+
if (c && typeof c.getRandomValues === "function") {
|
|
40
|
+
c.getRandomValues(out);
|
|
41
|
+
return out;
|
|
42
|
+
}
|
|
43
|
+
for (let i = 0; i < 16; i++)
|
|
44
|
+
out[i] = Math.floor(Math.random() * 256);
|
|
45
|
+
return out;
|
|
46
|
+
}
|
|
47
|
+
/** The default id minter: UUIDv7 from the injected clock. */
|
|
48
|
+
function createUuid(clock) {
|
|
49
|
+
return () => uuidv7(clock.now(), randomBytes16());
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=ids.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ids.js","sourceRoot":"","sources":["../../src/core/ids.ts"],"names":[],"mappings":";;AAaA,wBAWC;AAOD,sCASC;AAGD,gCAEC;AA3CD,MAAM,GAAG,GAAG,CAAC,KAAiB,EAAE,IAAY,EAAE,EAAU,EAAE,EAAE;IAC1D,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE;QAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAChF,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAEF;;;;GAIG;AACH,SAAgB,MAAM,CAAC,KAAa,EAAE,MAAkB;;IACtD,MAAM,CAAC,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;IAC7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE;QAAE,CAAC,CAAC,CAAC,CAAC,GAAG,MAAA,MAAM,CAAC,CAAC,CAAC,mCAAI,CAAC,CAAC;IACnD,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;QACf,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;IAC1B,CAAC;IACD,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,YAAY;IACzC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,eAAe;IAC5C,OAAO,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC;AAC9F,CAAC;AAED;;;;GAIG;AACH,SAAgB,aAAa;IAC3B,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;IAC/B,MAAM,CAAC,GAAI,UAA+E,CAAC,MAAM,CAAC;IAClG,IAAI,CAAC,IAAI,OAAO,CAAC,CAAC,eAAe,KAAK,UAAU,EAAE,CAAC;QACjD,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;QACvB,OAAO,GAAG,CAAC;IACb,CAAC;IACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE;QAAE,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC;IACtE,OAAO,GAAG,CAAC;AACb,CAAC;AAED,6DAA6D;AAC7D,SAAgB,UAAU,CAAC,KAAY;IACrC,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,CAAC,CAAC;AACpD,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export { captureRunContext } from "./context";
|
|
2
|
+
export type { RunContextInput, WireRunContext } from "./context";
|
|
3
|
+
export { consoleDiagnostics, safeDiagnostics } from "./diagnostics";
|
|
4
|
+
export type { Diagnostic, DiagnosticHandler } from "./diagnostics";
|
|
5
|
+
export { createDelivery } from "./delivery";
|
|
6
|
+
export type { Delivery, DeliveryOptions, Outbound, RetryPolicy } from "./delivery";
|
|
7
|
+
export { createHttpSink } from "./httpSink";
|
|
8
|
+
export type { HttpSinkOptions } from "./httpSink";
|
|
9
|
+
export { createUuid, randomBytes16, uuidv7 } from "./ids";
|
|
10
|
+
export { normalizeResult } from "./sink";
|
|
11
|
+
export type { Sink, SinkOutcome, SinkResult } from "./sink";
|
|
12
|
+
export { createSerialStore, memoryStorage } from "./storage";
|
|
13
|
+
export type { KeyValueStorage, SerialStore } from "./storage";
|
|
14
|
+
export { codePointLength, utf8ByteLength } from "./text";
|
|
15
|
+
export { systemClock, systemTimers, toTimestamp } from "./time";
|
|
16
|
+
export type { Clock, Timers } from "./time";
|
|
17
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACpE,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,YAAY,EAAE,QAAQ,EAAE,eAAe,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACnF,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,YAAY,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AACzC,YAAY,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC7D,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAChE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// @rocapine/rocalytics-sdk/core: shared building blocks for the surface subpaths.
|
|
3
|
+
// Internal: exported so a custom sink or another surface can use it, with no
|
|
4
|
+
// stability promise beyond what /onboarding re-exports.
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.toTimestamp = exports.systemTimers = exports.systemClock = exports.utf8ByteLength = exports.codePointLength = exports.memoryStorage = exports.createSerialStore = exports.normalizeResult = exports.uuidv7 = exports.randomBytes16 = exports.createUuid = exports.createHttpSink = exports.createDelivery = exports.safeDiagnostics = exports.consoleDiagnostics = exports.captureRunContext = void 0;
|
|
7
|
+
var context_1 = require("./context");
|
|
8
|
+
Object.defineProperty(exports, "captureRunContext", { enumerable: true, get: function () { return context_1.captureRunContext; } });
|
|
9
|
+
var diagnostics_1 = require("./diagnostics");
|
|
10
|
+
Object.defineProperty(exports, "consoleDiagnostics", { enumerable: true, get: function () { return diagnostics_1.consoleDiagnostics; } });
|
|
11
|
+
Object.defineProperty(exports, "safeDiagnostics", { enumerable: true, get: function () { return diagnostics_1.safeDiagnostics; } });
|
|
12
|
+
var delivery_1 = require("./delivery");
|
|
13
|
+
Object.defineProperty(exports, "createDelivery", { enumerable: true, get: function () { return delivery_1.createDelivery; } });
|
|
14
|
+
var httpSink_1 = require("./httpSink");
|
|
15
|
+
Object.defineProperty(exports, "createHttpSink", { enumerable: true, get: function () { return httpSink_1.createHttpSink; } });
|
|
16
|
+
var ids_1 = require("./ids");
|
|
17
|
+
Object.defineProperty(exports, "createUuid", { enumerable: true, get: function () { return ids_1.createUuid; } });
|
|
18
|
+
Object.defineProperty(exports, "randomBytes16", { enumerable: true, get: function () { return ids_1.randomBytes16; } });
|
|
19
|
+
Object.defineProperty(exports, "uuidv7", { enumerable: true, get: function () { return ids_1.uuidv7; } });
|
|
20
|
+
var sink_1 = require("./sink");
|
|
21
|
+
Object.defineProperty(exports, "normalizeResult", { enumerable: true, get: function () { return sink_1.normalizeResult; } });
|
|
22
|
+
var storage_1 = require("./storage");
|
|
23
|
+
Object.defineProperty(exports, "createSerialStore", { enumerable: true, get: function () { return storage_1.createSerialStore; } });
|
|
24
|
+
Object.defineProperty(exports, "memoryStorage", { enumerable: true, get: function () { return storage_1.memoryStorage; } });
|
|
25
|
+
var text_1 = require("./text");
|
|
26
|
+
Object.defineProperty(exports, "codePointLength", { enumerable: true, get: function () { return text_1.codePointLength; } });
|
|
27
|
+
Object.defineProperty(exports, "utf8ByteLength", { enumerable: true, get: function () { return text_1.utf8ByteLength; } });
|
|
28
|
+
var time_1 = require("./time");
|
|
29
|
+
Object.defineProperty(exports, "systemClock", { enumerable: true, get: function () { return time_1.systemClock; } });
|
|
30
|
+
Object.defineProperty(exports, "systemTimers", { enumerable: true, get: function () { return time_1.systemTimers; } });
|
|
31
|
+
Object.defineProperty(exports, "toTimestamp", { enumerable: true, get: function () { return time_1.toTimestamp; } });
|
|
32
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":";AAAA,kFAAkF;AAClF,6EAA6E;AAC7E,wDAAwD;;;AAExD,qCAA8C;AAArC,4GAAA,iBAAiB,OAAA;AAE1B,6CAAoE;AAA3D,iHAAA,kBAAkB,OAAA;AAAE,8GAAA,eAAe,OAAA;AAE5C,uCAA4C;AAAnC,0GAAA,cAAc,OAAA;AAEvB,uCAA4C;AAAnC,0GAAA,cAAc,OAAA;AAEvB,6BAA0D;AAAjD,iGAAA,UAAU,OAAA;AAAE,oGAAA,aAAa,OAAA;AAAE,6FAAA,MAAM,OAAA;AAC1C,+BAAyC;AAAhC,uGAAA,eAAe,OAAA;AAExB,qCAA6D;AAApD,4GAAA,iBAAiB,OAAA;AAAE,wGAAA,aAAa,OAAA;AAEzC,+BAAyD;AAAhD,uGAAA,eAAe,OAAA;AAAE,sGAAA,cAAc,OAAA;AACxC,+BAAgE;AAAvD,mGAAA,WAAW,OAAA;AAAE,oGAAA,YAAY,OAAA;AAAE,mGAAA,WAAW,OAAA"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The three outcomes an ingest can give a snapshot, carried in its response
|
|
3
|
+
* body. Anything else (no response, an error, a response without one of these)
|
|
4
|
+
* is transient: the snapshot is kept and sent again.
|
|
5
|
+
*/
|
|
6
|
+
export type SinkOutcome = "accepted" | "ignored" | "rejected";
|
|
7
|
+
export type SinkResult = {
|
|
8
|
+
outcome: SinkOutcome;
|
|
9
|
+
reason?: string;
|
|
10
|
+
} | {
|
|
11
|
+
outcome: "transient";
|
|
12
|
+
reason?: string;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Delivers one payload somewhere. A sink reports what happened; it does not
|
|
16
|
+
* retry, and it may throw: the caller treats a throw as transient.
|
|
17
|
+
*
|
|
18
|
+
* The caller sends one payload of a run at a time, and counts a send with no
|
|
19
|
+
* answer after its attempt timeout (30 s by default) as transient. A sink that
|
|
20
|
+
* keeps working past that timeout can therefore overlap with the retry. Both
|
|
21
|
+
* carry the same seq and body, so this is safe against an ingest that ignores
|
|
22
|
+
* an equal seq, but a sink should give up before the attempt timeout (the
|
|
23
|
+
* stock HTTP sink gives up after 15 s).
|
|
24
|
+
*/
|
|
25
|
+
export interface Sink<T = unknown> {
|
|
26
|
+
/**
|
|
27
|
+
* Where payloads go, such as the collector's URL. Two sinks with the same
|
|
28
|
+
* destination are interchangeable: a reconfigure hands the old tracker's
|
|
29
|
+
* unsent snapshots to the new one, and stored ones are sent by either.
|
|
30
|
+
* Without it, only the same sink object counts as the same destination.
|
|
31
|
+
* A test double must not claim a real destination: the stock sinks mark
|
|
32
|
+
* theirs ` (custom fetch)` when given a `fetch`. Headers are not part of it.
|
|
33
|
+
*/
|
|
34
|
+
readonly destination?: string;
|
|
35
|
+
send(payload: T): Promise<SinkResult> | SinkResult;
|
|
36
|
+
}
|
|
37
|
+
/** Reads a sink's answer strictly: only the three named outcomes end a send. */
|
|
38
|
+
export declare function normalizeResult(value: unknown): SinkResult;
|
|
39
|
+
//# sourceMappingURL=sink.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sink.d.ts","sourceRoot":"","sources":["../../src/core/sink.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,CAAC;AAE9D,MAAM,MAAM,UAAU,GAClB;IAAE,OAAO,EAAE,WAAW,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GACzC;IAAE,OAAO,EAAE,WAAW,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE9C;;;;;;;;;;GAUG;AACH,MAAM,WAAW,IAAI,CAAC,CAAC,GAAG,OAAO;IAC/B;;;;;;;OAOG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,UAAU,CAAC;CACpD;AAED,gFAAgF;AAChF,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,CAS1D"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.normalizeResult = normalizeResult;
|
|
4
|
+
/** Reads a sink's answer strictly: only the three named outcomes end a send. */
|
|
5
|
+
function normalizeResult(value) {
|
|
6
|
+
if (value && typeof value === "object") {
|
|
7
|
+
const { outcome, reason } = value;
|
|
8
|
+
if (outcome === "accepted" || outcome === "ignored" || outcome === "rejected") {
|
|
9
|
+
return typeof reason === "string" ? { outcome, reason } : { outcome };
|
|
10
|
+
}
|
|
11
|
+
if (typeof reason === "string")
|
|
12
|
+
return { outcome: "transient", reason };
|
|
13
|
+
}
|
|
14
|
+
return { outcome: "transient" };
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=sink.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sink.js","sourceRoot":"","sources":["../../src/core/sink.ts"],"names":[],"mappings":";;AAoCA,0CASC;AAVD,gFAAgF;AAChF,SAAgB,eAAe,CAAC,KAAc;IAC5C,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,KAAgD,CAAC;QAC7E,IAAI,OAAO,KAAK,UAAU,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;YAC9E,OAAO,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;QACxE,CAAC;QACD,IAAI,OAAO,MAAM,KAAK,QAAQ;YAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC;IAC1E,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A string key-value store. The shape matches `@react-native-async-storage/async-storage`
|
|
3
|
+
* and `localStorage`, so either can be passed as is; this package depends on neither.
|
|
4
|
+
*/
|
|
5
|
+
export interface KeyValueStorage {
|
|
6
|
+
getItem(key: string): string | null | Promise<string | null>;
|
|
7
|
+
setItem(key: string, value: string): void | Promise<void>;
|
|
8
|
+
removeItem(key: string): void | Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
/** An in-memory `KeyValueStorage`. Survives nothing; useful for tests and for opting out of persistence. */
|
|
11
|
+
export declare function memoryStorage(): KeyValueStorage & {
|
|
12
|
+
dump(): Record<string, string>;
|
|
13
|
+
};
|
|
14
|
+
/** What a read found: a value (or nothing stored), a value that is not JSON, or no answer from storage at all. */
|
|
15
|
+
export type ReadResult<T> = {
|
|
16
|
+
status: "ok";
|
|
17
|
+
value: T | null;
|
|
18
|
+
} | {
|
|
19
|
+
status: "invalid";
|
|
20
|
+
error: unknown;
|
|
21
|
+
} | {
|
|
22
|
+
status: "failed";
|
|
23
|
+
error: unknown;
|
|
24
|
+
};
|
|
25
|
+
export interface SerialStore<T> {
|
|
26
|
+
/** Reads the value, after every write queued before it. Null when absent or unreadable. */
|
|
27
|
+
load(): Promise<T | null>;
|
|
28
|
+
/**
|
|
29
|
+
* Reads the value, after every write queued before it, telling a value that
|
|
30
|
+
* is not JSON (`invalid`) from storage that did not answer (`failed`). A
|
|
31
|
+
* failed read is retried once, in the same turn, before it counts as failed.
|
|
32
|
+
* `waitFirst` is awaited inside that turn, before reading: operations queued
|
|
33
|
+
* after this read still wait for it, so it can be ordered behind work done
|
|
34
|
+
* elsewhere (another store's last writes) without them overtaking it.
|
|
35
|
+
*/
|
|
36
|
+
read(waitFirst?: Promise<unknown>): Promise<ReadResult<T>>;
|
|
37
|
+
/** Queues a write (null removes the key). Never throws; failures go to `onError`. */
|
|
38
|
+
save(value: T | null): void;
|
|
39
|
+
/**
|
|
40
|
+
* Queues a write whose value is computed when its turn comes, so it is the
|
|
41
|
+
* latest one; `undefined` skips the write. Resolves once done. Never rejects.
|
|
42
|
+
*/
|
|
43
|
+
saveWith(produce: () => T | null | undefined | Promise<T | null | undefined>): Promise<void>;
|
|
44
|
+
/** Resolves once every queued operation has finished. */
|
|
45
|
+
idle(): Promise<void>;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* JSON values under one key, with every read and write applied in call order,
|
|
49
|
+
* so an older write can never land after a newer one.
|
|
50
|
+
*/
|
|
51
|
+
export declare function createSerialStore<T>(storage: KeyValueStorage, key: string, onError: (error: unknown) => void): SerialStore<T>;
|
|
52
|
+
//# sourceMappingURL=storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/core/storage.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC7D,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/C;AAED,4GAA4G;AAC5G,wBAAgB,aAAa,IAAI,eAAe,GAAG;IAAE,IAAI,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAQpF;AAED,kHAAkH;AAClH,MAAM,MAAM,UAAU,CAAC,CAAC,IACpB;IAAE,MAAM,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,CAAC,GAAG,IAAI,CAAA;CAAE,GACjC;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GACrC;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC;AAEzC,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,2FAA2F;IAC3F,IAAI,IAAI,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAC1B;;;;;;;OAOG;IACH,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3D,qFAAqF;IACrF,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;IAC5B;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7F,yDAAyD;IACzD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EACjC,OAAO,EAAE,eAAe,EACxB,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GAChC,WAAW,CAAC,CAAC,CAAC,CAqDhB"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.memoryStorage = memoryStorage;
|
|
4
|
+
exports.createSerialStore = createSerialStore;
|
|
5
|
+
/** An in-memory `KeyValueStorage`. Survives nothing; useful for tests and for opting out of persistence. */
|
|
6
|
+
function memoryStorage() {
|
|
7
|
+
const map = new Map();
|
|
8
|
+
return {
|
|
9
|
+
getItem: (k) => { var _a; return (_a = map.get(k)) !== null && _a !== void 0 ? _a : null; },
|
|
10
|
+
setItem: (k, v) => void map.set(k, v),
|
|
11
|
+
removeItem: (k) => void map.delete(k),
|
|
12
|
+
dump: () => Object.fromEntries(map),
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* JSON values under one key, with every read and write applied in call order,
|
|
17
|
+
* so an older write can never land after a newer one.
|
|
18
|
+
*/
|
|
19
|
+
function createSerialStore(storage, key, onError) {
|
|
20
|
+
const queue = { chain: Promise.resolve() };
|
|
21
|
+
const enqueue = (op, fallback) => {
|
|
22
|
+
const next = queue.chain.then(op).catch((e) => {
|
|
23
|
+
onError(e);
|
|
24
|
+
return fallback;
|
|
25
|
+
});
|
|
26
|
+
queue.chain = next;
|
|
27
|
+
return next;
|
|
28
|
+
};
|
|
29
|
+
const getRaw = async () => {
|
|
30
|
+
try {
|
|
31
|
+
return await storage.getItem(key);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return await storage.getItem(key); // one retry, still inside this turn of the queue
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
const read = (waitFirst) => enqueue(async () => {
|
|
38
|
+
if (waitFirst)
|
|
39
|
+
await waitFirst.catch(() => undefined);
|
|
40
|
+
let raw;
|
|
41
|
+
try {
|
|
42
|
+
raw = await getRaw();
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
return { status: "failed", error };
|
|
46
|
+
}
|
|
47
|
+
if (raw == null)
|
|
48
|
+
return { status: "ok", value: null };
|
|
49
|
+
try {
|
|
50
|
+
return { status: "ok", value: JSON.parse(raw) };
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
return { status: "invalid", error };
|
|
54
|
+
}
|
|
55
|
+
}, { status: "failed", error: undefined });
|
|
56
|
+
const write = async (value) => {
|
|
57
|
+
if (value === null)
|
|
58
|
+
await storage.removeItem(key);
|
|
59
|
+
else
|
|
60
|
+
await storage.setItem(key, JSON.stringify(value));
|
|
61
|
+
};
|
|
62
|
+
return {
|
|
63
|
+
load: () => read().then((r) => {
|
|
64
|
+
if (r.status === "ok")
|
|
65
|
+
return r.value;
|
|
66
|
+
onError(r.error);
|
|
67
|
+
return null;
|
|
68
|
+
}),
|
|
69
|
+
read,
|
|
70
|
+
save: (value) => void enqueue(() => write(value), undefined),
|
|
71
|
+
saveWith: (produce) => enqueue(async () => {
|
|
72
|
+
const value = await produce();
|
|
73
|
+
if (value !== undefined)
|
|
74
|
+
await write(value);
|
|
75
|
+
}, undefined),
|
|
76
|
+
idle: () => enqueue(() => undefined, undefined),
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/core/storage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UTF-8 length of `s` in bytes, without `TextEncoder` or `Buffer` (neither is
|
|
3
|
+
* guaranteed on every JavaScript runtime an app ships on). A lone surrogate
|
|
4
|
+
* counts as the 3-byte replacement character, as an encoder would write it.
|
|
5
|
+
*/
|
|
6
|
+
export declare function utf8ByteLength(s: string): number;
|
|
7
|
+
/** Length in code points: what JSON Schema's `minLength` / `maxLength` count. */
|
|
8
|
+
export declare function codePointLength(s: string): number;
|
|
9
|
+
//# sourceMappingURL=text.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../src/core/text.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAiBhD;AAED,iFAAiF;AACjF,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAWjD"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.utf8ByteLength = utf8ByteLength;
|
|
4
|
+
exports.codePointLength = codePointLength;
|
|
5
|
+
/**
|
|
6
|
+
* UTF-8 length of `s` in bytes, without `TextEncoder` or `Buffer` (neither is
|
|
7
|
+
* guaranteed on every JavaScript runtime an app ships on). A lone surrogate
|
|
8
|
+
* counts as the 3-byte replacement character, as an encoder would write it.
|
|
9
|
+
*/
|
|
10
|
+
function utf8ByteLength(s) {
|
|
11
|
+
let bytes = 0;
|
|
12
|
+
for (let i = 0; i < s.length; i++) {
|
|
13
|
+
const c = s.charCodeAt(i);
|
|
14
|
+
if (c < 0x80)
|
|
15
|
+
bytes += 1;
|
|
16
|
+
else if (c < 0x800)
|
|
17
|
+
bytes += 2;
|
|
18
|
+
else if (c >= 0xd800 && c <= 0xdbff && i + 1 < s.length) {
|
|
19
|
+
const next = s.charCodeAt(i + 1);
|
|
20
|
+
if (next >= 0xdc00 && next <= 0xdfff) {
|
|
21
|
+
bytes += 4;
|
|
22
|
+
i++;
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
bytes += 3;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
else
|
|
29
|
+
bytes += 3;
|
|
30
|
+
}
|
|
31
|
+
return bytes;
|
|
32
|
+
}
|
|
33
|
+
/** Length in code points: what JSON Schema's `minLength` / `maxLength` count. */
|
|
34
|
+
function codePointLength(s) {
|
|
35
|
+
let n = 0;
|
|
36
|
+
for (let i = 0; i < s.length; i++) {
|
|
37
|
+
const c = s.charCodeAt(i);
|
|
38
|
+
if (c >= 0xd800 && c <= 0xdbff && i + 1 < s.length) {
|
|
39
|
+
const next = s.charCodeAt(i + 1);
|
|
40
|
+
if (next >= 0xdc00 && next <= 0xdfff)
|
|
41
|
+
i++;
|
|
42
|
+
}
|
|
43
|
+
n++;
|
|
44
|
+
}
|
|
45
|
+
return n;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=text.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text.js","sourceRoot":"","sources":["../../src/core/text.ts"],"names":[],"mappings":";;AAKA,wCAiBC;AAGD,0CAWC;AApCD;;;;GAIG;AACH,SAAgB,cAAc,CAAC,CAAS;IACtC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,MAAM,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QAC1B,IAAI,CAAC,GAAG,IAAI;YAAE,KAAK,IAAI,CAAC,CAAC;aACpB,IAAI,CAAC,GAAG,KAAK;YAAE,KAAK,IAAI,CAAC,CAAC;aAC1B,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC;YACxD,MAAM,IAAI,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACjC,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,EAAE,CAAC;gBACrC,KAAK,IAAI,CAAC,CAAC;gBACX,CAAC,EAAE,CAAC;YACN,CAAC;iBAAM,CAAC;gBACN,KAAK,IAAI,CAAC,CAAC;YACb,CAAC;QACH,CAAC;;YAAM,KAAK,IAAI,CAAC,CAAC;IACpB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,iFAAiF;AACjF,SAAgB,eAAe,CAAC,CAAS;IACvC,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,MAAM,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QAC1B,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC;YACnD,MAAM,IAAI,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACjC,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM;gBAAE,CAAC,EAAE,CAAC;QAC5C,CAAC;QACD,CAAC,EAAE,CAAC;IACN,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** A source of the current time, in milliseconds since the epoch. Injected so tests can fix it. */
|
|
2
|
+
export interface Clock {
|
|
3
|
+
now(): number;
|
|
4
|
+
}
|
|
5
|
+
/** The two timer functions the core uses. Injected so tests can drive time. */
|
|
6
|
+
export interface Timers {
|
|
7
|
+
setTimeout(fn: () => void, ms: number): unknown;
|
|
8
|
+
clearTimeout(handle: unknown): void;
|
|
9
|
+
}
|
|
10
|
+
export declare const systemClock: Clock;
|
|
11
|
+
export declare const systemTimers: Timers;
|
|
12
|
+
/**
|
|
13
|
+
* A UTC timestamp with exactly three fractional digits and a `Z`, e.g.
|
|
14
|
+
* `2026-01-10T09:00:00.000Z`: the only timestamp form the contract accepts.
|
|
15
|
+
* `toISOString` produces exactly that for every year from 0 to 9999.
|
|
16
|
+
*/
|
|
17
|
+
export declare function toTimestamp(ms: number): string;
|
|
18
|
+
//# sourceMappingURL=time.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"time.d.ts","sourceRoot":"","sources":["../../src/core/time.ts"],"names":[],"mappings":"AAAA,mGAAmG;AACnG,MAAM,WAAW,KAAK;IACpB,GAAG,IAAI,MAAM,CAAC;CACf;AAED,+EAA+E;AAC/E,MAAM,WAAW,MAAM;IACrB,UAAU,CAAC,EAAE,EAAE,MAAM,IAAI,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;IAChD,YAAY,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;CACrC;AAED,eAAO,MAAM,WAAW,EAAE,KAAiC,CAAC;AAE5D,eAAO,MAAM,YAAY,EAAE,MAG1B,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAE9C"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.systemTimers = exports.systemClock = void 0;
|
|
4
|
+
exports.toTimestamp = toTimestamp;
|
|
5
|
+
exports.systemClock = { now: () => Date.now() };
|
|
6
|
+
exports.systemTimers = {
|
|
7
|
+
setTimeout: (fn, ms) => setTimeout(fn, ms),
|
|
8
|
+
clearTimeout: (handle) => clearTimeout(handle),
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* A UTC timestamp with exactly three fractional digits and a `Z`, e.g.
|
|
12
|
+
* `2026-01-10T09:00:00.000Z`: the only timestamp form the contract accepts.
|
|
13
|
+
* `toISOString` produces exactly that for every year from 0 to 9999.
|
|
14
|
+
*/
|
|
15
|
+
function toTimestamp(ms) {
|
|
16
|
+
return new Date(ms).toISOString();
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=time.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"time.js","sourceRoot":"","sources":["../../src/core/time.ts"],"names":[],"mappings":";;;AAuBA,kCAEC;AAdY,QAAA,WAAW,GAAU,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;AAE/C,QAAA,YAAY,GAAW;IAClC,UAAU,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,EAAE,EAAE,EAAE,CAAC;IAC1C,YAAY,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,YAAY,CAAC,MAAuC,CAAC;CAChF,CAAC;AAEF;;;;GAIG;AACH,SAAgB,WAAW,CAAC,EAAU;IACpC,OAAO,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;AACpC,CAAC"}
|