@pwa-platform/sw-runtime 0.1.0-beta.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/LICENSE +21 -0
- package/README.md +9 -0
- package/dist/build/config.d.ts +10 -0
- package/dist/build/config.d.ts.map +1 -0
- package/dist/build/config.js +40 -0
- package/dist/build/config.js.map +1 -0
- package/dist/build/index.d.ts +6 -0
- package/dist/build/index.d.ts.map +1 -0
- package/dist/build/index.js +9 -0
- package/dist/build/index.js.map +1 -0
- package/dist/build/inject.d.ts +13 -0
- package/dist/build/inject.d.ts.map +1 -0
- package/dist/build/inject.js +29 -0
- package/dist/build/inject.js.map +1 -0
- package/dist/entries/platform-worker-entry.d.ts +2 -0
- package/dist/entries/platform-worker-entry.d.ts.map +1 -0
- package/dist/entries/platform-worker-entry.js +3 -0
- package/dist/entries/platform-worker-entry.js.map +1 -0
- package/dist/entries/recovery-worker-entry.d.ts +2 -0
- package/dist/entries/recovery-worker-entry.d.ts.map +1 -0
- package/dist/entries/recovery-worker-entry.js +4 -0
- package/dist/entries/recovery-worker-entry.js.map +1 -0
- package/dist/messages/index.d.ts +49 -0
- package/dist/messages/index.d.ts.map +1 -0
- package/dist/messages/index.js +90 -0
- package/dist/messages/index.js.map +1 -0
- package/dist/push-payload/index.d.ts +46 -0
- package/dist/push-payload/index.d.ts.map +1 -0
- package/dist/push-payload/index.js +115 -0
- package/dist/push-payload/index.js.map +1 -0
- package/dist/recovery-worker/index.d.ts +18 -0
- package/dist/recovery-worker/index.d.ts.map +1 -0
- package/dist/recovery-worker/index.js +60 -0
- package/dist/recovery-worker/index.js.map +1 -0
- package/dist/shared/config.d.ts +71 -0
- package/dist/shared/config.d.ts.map +1 -0
- package/dist/shared/config.js +216 -0
- package/dist/shared/config.js.map +1 -0
- package/dist/shared/path-match.d.ts +20 -0
- package/dist/shared/path-match.d.ts.map +1 -0
- package/dist/shared/path-match.js +56 -0
- package/dist/shared/path-match.js.map +1 -0
- package/dist/worker/decide.d.ts +65 -0
- package/dist/worker/decide.d.ts.map +1 -0
- package/dist/worker/decide.js +65 -0
- package/dist/worker/decide.js.map +1 -0
- package/dist/worker/handlers.d.ts +16 -0
- package/dist/worker/handlers.d.ts.map +1 -0
- package/dist/worker/handlers.js +196 -0
- package/dist/worker/handlers.js.map +1 -0
- package/dist/worker/index.d.ts +17 -0
- package/dist/worker/index.d.ts.map +1 -0
- package/dist/worker/index.js +16 -0
- package/dist/worker/index.js.map +1 -0
- package/dist/worker/notification-target.d.ts +9 -0
- package/dist/worker/notification-target.d.ts.map +1 -0
- package/dist/worker/notification-target.js +28 -0
- package/dist/worker/notification-target.js.map +1 -0
- package/dist/worker/offline-write-flush.d.ts +10 -0
- package/dist/worker/offline-write-flush.d.ts.map +1 -0
- package/dist/worker/offline-write-flush.js +32 -0
- package/dist/worker/offline-write-flush.js.map +1 -0
- package/dist/worker/offline-write-intent.d.ts +36 -0
- package/dist/worker/offline-write-intent.d.ts.map +1 -0
- package/dist/worker/offline-write-intent.js +84 -0
- package/dist/worker/offline-write-intent.js.map +1 -0
- package/dist/worker/offline-write-store.d.ts +27 -0
- package/dist/worker/offline-write-store.d.ts.map +1 -0
- package/dist/worker/offline-write-store.js +152 -0
- package/dist/worker/offline-write-store.js.map +1 -0
- package/package.json +65 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 PWA Platform contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# @pwa-platform/sw-runtime
|
|
2
|
+
|
|
3
|
+
Service worker and recovery runtime for PWA Platform.
|
|
4
|
+
|
|
5
|
+
Internal platform service worker and recovery worker implementation. Applications should not register its entries directly.
|
|
6
|
+
|
|
7
|
+
This is a `0.1.0` prerelease. It provides online use, installation integration, static precaching, a safe offline fallback, and controlled updates. It does not enable runtime business API caching, private data caching, automatic write replay, or Push for applications. Production deployment requires the application and infrastructure checks described in the PWA Platform release runbook.
|
|
8
|
+
|
|
9
|
+
License: MIT.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type PwaPlan } from "@pwa-platform/contracts";
|
|
2
|
+
import { type PwaPlatformWorkerConfig, type PwaRecoveryWorkerConfig } from "../shared/config.js";
|
|
3
|
+
/**
|
|
4
|
+
* The platform worker's runtime config: only the plan fields the worker reads, with the precache cache name computed
|
|
5
|
+
* by contracts. Throws for an invalid plan (the message lists diagnostic codes and paths only).
|
|
6
|
+
*/
|
|
7
|
+
export declare function createPlatformWorkerConfig(plan: PwaPlan): PwaPlatformWorkerConfig;
|
|
8
|
+
/** The recovery worker's config: the app's cache prefix computed by contracts. Throws for an invalid plan. */
|
|
9
|
+
export declare function createRecoveryWorkerConfig(plan: PwaPlan): PwaRecoveryWorkerConfig;
|
|
10
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/build/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2C,KAAK,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAChG,OAAO,EAGL,KAAK,uBAAuB,EAC5B,KAAK,uBAAuB,EAC7B,MAAM,qBAAqB,CAAC;AAE7B;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,OAAO,GAAG,uBAAuB,CAcjF;AAED,8GAA8G;AAC9G,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,OAAO,GAAG,uBAAuB,CAQjF"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { appCachePrefix, cacheName, validatePlan } from "@pwa-platform/contracts";
|
|
2
|
+
import { validatePlatformWorkerConfig, validateRecoveryWorkerConfig, } from "../shared/config.js";
|
|
3
|
+
/**
|
|
4
|
+
* The platform worker's runtime config: only the plan fields the worker reads, with the precache cache name computed
|
|
5
|
+
* by contracts. Throws for an invalid plan (the message lists diagnostic codes and paths only).
|
|
6
|
+
*/
|
|
7
|
+
export function createPlatformWorkerConfig(plan) {
|
|
8
|
+
const validated = validPlan(plan);
|
|
9
|
+
const { identity, requestBaselineDenials, pathRules, offlineFallback, updateMode } = validated;
|
|
10
|
+
return validatePlatformWorkerConfig({
|
|
11
|
+
kind: "platform",
|
|
12
|
+
version: 1,
|
|
13
|
+
scope: identity.scope,
|
|
14
|
+
precacheCacheName: cacheName(identity, "precache"),
|
|
15
|
+
requestBaselineDenials: [...requestBaselineDenials],
|
|
16
|
+
pathRules: pathRules.map(({ pathPrefix, action }) => ({ pathPrefix, action })),
|
|
17
|
+
offlineFallback: offlineFallback.enabled ? { enabled: true, path: offlineFallback.path } : { enabled: false },
|
|
18
|
+
updateMode,
|
|
19
|
+
offlineWrites: validated.schemaVersion === 2 ? validated.offlineWrites : { enabled: false },
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
/** The recovery worker's config: the app's cache prefix computed by contracts. Throws for an invalid plan. */
|
|
23
|
+
export function createRecoveryWorkerConfig(plan) {
|
|
24
|
+
const { identity } = validPlan(plan);
|
|
25
|
+
return validateRecoveryWorkerConfig({
|
|
26
|
+
kind: "recovery",
|
|
27
|
+
version: 1,
|
|
28
|
+
appCachePrefix: appCachePrefix(identity),
|
|
29
|
+
offlineWriteDatabaseName: `pwa-offline-write:${encodeURIComponent(identity.appId)}:${encodeURIComponent(identity.environment)}:${encodeURIComponent(identity.cacheNamespaceSeed)}`,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
function validPlan(plan) {
|
|
33
|
+
const result = validatePlan(plan);
|
|
34
|
+
if (!result.ok) {
|
|
35
|
+
const findings = result.diagnostics.map(({ code, path }) => `${code} at ${path === "" ? "(root)" : path}`);
|
|
36
|
+
throw new Error(`Cannot create a worker config from an invalid PwaPlan: ${findings.join(", ")}`);
|
|
37
|
+
}
|
|
38
|
+
return result.value;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/build/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,YAAY,EAAgB,MAAM,yBAAyB,CAAC;AAChG,OAAO,EACL,4BAA4B,EAC5B,4BAA4B,GAG7B,MAAM,qBAAqB,CAAC;AAE7B;;;GAGG;AACH,MAAM,UAAU,0BAA0B,CAAC,IAAa;IACtD,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,EAAE,QAAQ,EAAE,sBAAsB,EAAE,SAAS,EAAE,eAAe,EAAE,UAAU,EAAE,GAAG,SAAS,CAAC;IAC/F,OAAO,4BAA4B,CAAC;QAClC,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,CAAC;QACV,KAAK,EAAE,QAAQ,CAAC,KAAK;QACrB,iBAAiB,EAAE,SAAS,CAAC,QAAQ,EAAE,UAAU,CAAC;QAClD,sBAAsB,EAAE,CAAC,GAAG,sBAAsB,CAAC;QACnD,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,CAAC;QAC9E,eAAe,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,eAAe,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE;QAC7G,UAAU;QACV,aAAa,EAAE,SAAS,CAAC,aAAa,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE;KAC5F,CAAC,CAAC;AACL,CAAC;AAED,8GAA8G;AAC9G,MAAM,UAAU,0BAA0B,CAAC,IAAa;IACtD,MAAM,EAAE,QAAQ,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IACrC,OAAO,4BAA4B,CAAC;QAClC,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,CAAC;QACV,cAAc,EAAE,cAAc,CAAC,QAAQ,CAAC;QACxC,wBAAwB,EAAE,qBAAqB,kBAAkB,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,kBAAkB,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,kBAAkB,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE;KACnL,CAAC,CAAC;AACL,CAAC;AAED,SAAS,SAAS,CAAC,IAAa;IAC9B,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IAClC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,GAAG,IAAI,OAAO,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAC3G,MAAM,IAAI,KAAK,CAAC,0DAA0D,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACnG,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,CAAC;AACtB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { createPlatformWorkerConfig, createRecoveryWorkerConfig } from "./config.js";
|
|
2
|
+
export { injectWorkerConfig, WORKER_CONFIG_INJECTION_POINT } from "./inject.js";
|
|
3
|
+
export { createPathMatcher } from "../shared/path-match.js";
|
|
4
|
+
export type { PwaPlatformWorkerConfig, PwaRecoveryWorkerConfig, PwaWorkerBaselineDenial, PwaWorkerConfig, PwaWorkerPath, PwaWorkerPathRule, PwaWorkerPathRuleAction, } from "../shared/config.js";
|
|
5
|
+
export type { PwaPathMatcher } from "../shared/path-match.js";
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/build/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,0BAA0B,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AACrF,OAAO,EAAE,kBAAkB,EAAE,6BAA6B,EAAE,MAAM,aAAa,CAAC;AAChF,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,YAAY,EACV,uBAAuB,EACvB,uBAAuB,EACvB,uBAAuB,EACvB,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,uBAAuB,GACxB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// Build-time entry (Node): creates the worker configs from a validated PwaPlan and injects them after bundling.
|
|
2
|
+
// Also re-exports the runtime path matcher (shared/path-match.ts) for hosts that need to classify a path against a
|
|
3
|
+
// plan's path rules outside of a worker — e.g. @pwa-platform/nuxt's build-time check for prerendered HTML that
|
|
4
|
+
// falls under a denied path rule (T6). path-match.ts itself imports nothing, so this entry still imports only
|
|
5
|
+
// @pwa-platform/contracts.
|
|
6
|
+
export { createPlatformWorkerConfig, createRecoveryWorkerConfig } from "./config.js";
|
|
7
|
+
export { injectWorkerConfig, WORKER_CONFIG_INJECTION_POINT } from "./inject.js";
|
|
8
|
+
export { createPathMatcher } from "../shared/path-match.js";
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/build/index.ts"],"names":[],"mappings":"AAAA,gHAAgH;AAChH,mHAAmH;AACnH,+GAA+G;AAC/G,8GAA8G;AAC9G,2BAA2B;AAC3B,OAAO,EAAE,0BAA0B,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AACrF,OAAO,EAAE,kBAAkB,EAAE,6BAA6B,EAAE,MAAM,aAAa,CAAC;AAChF,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type PwaWorkerConfig } from "../shared/config.js";
|
|
2
|
+
/** Injection point for the worker config; the bundled worker source must contain it exactly once. */
|
|
3
|
+
export declare const WORKER_CONFIG_INJECTION_POINT = "self.__PWA_WORKER_CONFIG";
|
|
4
|
+
/**
|
|
5
|
+
* Replaces the injection point in the bundled `workerSource` with `config` serialized as JSON. Call it after bundling,
|
|
6
|
+
* like the precache manifest injection (ADR-0011).
|
|
7
|
+
*
|
|
8
|
+
* The config is validated first and serialized from the validated copy, so the output does not depend on the key
|
|
9
|
+
* order of the given object. Throws when the config is invalid or the injection point does not occur exactly once.
|
|
10
|
+
* Pure and deterministic: no file access, bundling or minification.
|
|
11
|
+
*/
|
|
12
|
+
export declare function injectWorkerConfig(workerSource: string, config: PwaWorkerConfig): string;
|
|
13
|
+
//# sourceMappingURL=inject.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inject.d.ts","sourceRoot":"","sources":["../../src/build/inject.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEjF,qGAAqG;AACrG,eAAO,MAAM,6BAA6B,6BAA6B,CAAC;AAExE;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,MAAM,CAYxF"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { validateWorkerConfig } from "../shared/config.js";
|
|
2
|
+
/** Injection point for the worker config; the bundled worker source must contain it exactly once. */
|
|
3
|
+
export const WORKER_CONFIG_INJECTION_POINT = "self.__PWA_WORKER_CONFIG";
|
|
4
|
+
/**
|
|
5
|
+
* Replaces the injection point in the bundled `workerSource` with `config` serialized as JSON. Call it after bundling,
|
|
6
|
+
* like the precache manifest injection (ADR-0011).
|
|
7
|
+
*
|
|
8
|
+
* The config is validated first and serialized from the validated copy, so the output does not depend on the key
|
|
9
|
+
* order of the given object. Throws when the config is invalid or the injection point does not occur exactly once.
|
|
10
|
+
* Pure and deterministic: no file access, bundling or minification.
|
|
11
|
+
*/
|
|
12
|
+
export function injectWorkerConfig(workerSource, config) {
|
|
13
|
+
if (typeof workerSource !== "string")
|
|
14
|
+
throw new TypeError("The worker source must be a string");
|
|
15
|
+
const serialized = JSON.stringify(validateWorkerConfig(config));
|
|
16
|
+
const occurrences = countOccurrences(workerSource, WORKER_CONFIG_INJECTION_POINT);
|
|
17
|
+
if (occurrences !== 1) {
|
|
18
|
+
throw new Error(`Expected exactly one ${WORKER_CONFIG_INJECTION_POINT} injection point in the worker source, found ${occurrences}`);
|
|
19
|
+
}
|
|
20
|
+
const index = workerSource.indexOf(WORKER_CONFIG_INJECTION_POINT);
|
|
21
|
+
return `${workerSource.slice(0, index)}${serialized}${workerSource.slice(index + WORKER_CONFIG_INJECTION_POINT.length)}`;
|
|
22
|
+
}
|
|
23
|
+
function countOccurrences(text, search) {
|
|
24
|
+
let count = 0;
|
|
25
|
+
for (let index = text.indexOf(search); index !== -1; index = text.indexOf(search, index + search.length))
|
|
26
|
+
count += 1;
|
|
27
|
+
return count;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=inject.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inject.js","sourceRoot":"","sources":["../../src/build/inject.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAwB,MAAM,qBAAqB,CAAC;AAEjF,qGAAqG;AACrG,MAAM,CAAC,MAAM,6BAA6B,GAAG,0BAA0B,CAAC;AAExE;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAAC,YAAoB,EAAE,MAAuB;IAC9E,IAAI,OAAO,YAAY,KAAK,QAAQ;QAAE,MAAM,IAAI,SAAS,CAAC,oCAAoC,CAAC,CAAC;IAEhG,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAC;IAEhE,MAAM,WAAW,GAAG,gBAAgB,CAAC,YAAY,EAAE,6BAA6B,CAAC,CAAC;IAClF,IAAI,WAAW,KAAK,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,wBAAwB,6BAA6B,gDAAgD,WAAW,EAAE,CAAC,CAAC;IACtI,CAAC;IAED,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,6BAA6B,CAAC,CAAC;IAClE,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,UAAU,GAAG,YAAY,CAAC,KAAK,CAAC,KAAK,GAAG,6BAA6B,CAAC,MAAM,CAAC,EAAE,CAAC;AAC3H,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAY,EAAE,MAAc;IACpD,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,IAAI,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC;QAAE,KAAK,IAAI,CAAC,CAAC;IACrH,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platform-worker-entry.d.ts","sourceRoot":"","sources":["../../src/entries/platform-worker-entry.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platform-worker-entry.js","sourceRoot":"","sources":["../../src/entries/platform-worker-entry.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAQ5D,sBAAsB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,mBAAmB,EAAE,QAAQ,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recovery-worker-entry.d.ts","sourceRoot":"","sources":["../../src/entries/recovery-worker-entry.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// Script bundled by vite-adapter as the recovery worker: reads the injected recovery config.
|
|
2
|
+
import { registerRecoveryWorker } from "../recovery-worker/index.js";
|
|
3
|
+
registerRecoveryWorker({ scope: self, config: self.__PWA_WORKER_CONFIG });
|
|
4
|
+
//# sourceMappingURL=recovery-worker-entry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recovery-worker-entry.js","sourceRoot":"","sources":["../../src/entries/recovery-worker-entry.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAMrE,sBAAsB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,mBAAmB,EAAE,CAAC,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/** Message a page posts to the waiting platform worker once the user accepts an update. */
|
|
2
|
+
export type PwaSkipWaitingMessage = {
|
|
3
|
+
readonly type: "pwa:skip-waiting";
|
|
4
|
+
};
|
|
5
|
+
export declare const SKIP_WAITING_MESSAGE: PwaSkipWaitingMessage;
|
|
6
|
+
/**
|
|
7
|
+
* True only for a plain object (this realm's `Object.prototype` or a null prototype) whose single own property is a
|
|
8
|
+
* `type` data property equal to `"pwa:skip-waiting"`. Structured-cloned messages have that shape; accessors are
|
|
9
|
+
* never invoked.
|
|
10
|
+
*/
|
|
11
|
+
export declare function isSkipWaitingMessage(value: unknown): value is PwaSkipWaitingMessage;
|
|
12
|
+
export type PwaOfflineWriteIntentMessage = {
|
|
13
|
+
readonly targetId: string;
|
|
14
|
+
readonly path: string;
|
|
15
|
+
readonly body: unknown;
|
|
16
|
+
readonly idempotencyKey: string;
|
|
17
|
+
readonly sessionBinding: string;
|
|
18
|
+
};
|
|
19
|
+
export type PwaOfflineWriteMessage = {
|
|
20
|
+
readonly type: "pwa:offline-write:enqueue";
|
|
21
|
+
readonly version: 1;
|
|
22
|
+
readonly requestId: string;
|
|
23
|
+
readonly intent: PwaOfflineWriteIntentMessage;
|
|
24
|
+
} | {
|
|
25
|
+
readonly type: "pwa:offline-write:flush";
|
|
26
|
+
readonly version: 1;
|
|
27
|
+
readonly requestId: string;
|
|
28
|
+
readonly sessionBinding: string;
|
|
29
|
+
} | {
|
|
30
|
+
readonly type: "pwa:offline-write:clear";
|
|
31
|
+
readonly version: 1;
|
|
32
|
+
readonly requestId: string;
|
|
33
|
+
};
|
|
34
|
+
/** The only acknowledgement a page accepts before it unregisters after an offline-write clear request. */
|
|
35
|
+
export type PwaOfflineWriteClearResult = {
|
|
36
|
+
readonly type: "pwa:offline-write:result";
|
|
37
|
+
readonly version: 1;
|
|
38
|
+
readonly requestId: string;
|
|
39
|
+
readonly status: "cleared";
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Recognizes only the v1 offline-write request envelopes. It deliberately validates only wire shape: target matching,
|
|
43
|
+
* JSON encoding, length limits and persistence are enforced together by the queue so a future caller cannot mistake
|
|
44
|
+
* a syntactically valid message for an accepted write. Reads never invoke a page-provided accessor.
|
|
45
|
+
*/
|
|
46
|
+
export declare function isOfflineWriteMessage(value: unknown): value is PwaOfflineWriteMessage;
|
|
47
|
+
/** Matches one closed clear acknowledgement without reading page- or worker-provided accessors. */
|
|
48
|
+
export declare function isOfflineWriteClearResult(value: unknown, requestId: string): value is PwaOfflineWriteClearResult;
|
|
49
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/messages/index.ts"],"names":[],"mappings":"AAAA,2FAA2F;AAC3F,MAAM,MAAM,qBAAqB,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAA;CAAE,CAAC;AAE1E,eAAO,MAAM,oBAAoB,EAAE,qBAAmE,CAAC;AAEvG;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,qBAAqB,CAQnF;AAED,MAAM,MAAM,4BAA4B,GAAG;IACzC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAC9B;IACE,QAAQ,CAAC,IAAI,EAAE,2BAA2B,CAAC;IAC3C,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACpB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,4BAA4B,CAAC;CAC/C,GACD;IACE,QAAQ,CAAC,IAAI,EAAE,yBAAyB,CAAC;IACzC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACpB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC,GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,yBAAyB,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AAElG,0GAA0G;AAC1G,MAAM,MAAM,0BAA0B,GAAG;IACvC,QAAQ,CAAC,IAAI,EAAE,0BAA0B,CAAC;IAC1C,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACpB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;CAC5B,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,sBAAsB,CA2BrF;AAED,mGAAmG;AACnG,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,KAAK,IAAI,0BAA0B,CAShH"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
export const SKIP_WAITING_MESSAGE = Object.freeze({ type: "pwa:skip-waiting" });
|
|
2
|
+
/**
|
|
3
|
+
* True only for a plain object (this realm's `Object.prototype` or a null prototype) whose single own property is a
|
|
4
|
+
* `type` data property equal to `"pwa:skip-waiting"`. Structured-cloned messages have that shape; accessors are
|
|
5
|
+
* never invoked.
|
|
6
|
+
*/
|
|
7
|
+
export function isSkipWaitingMessage(value) {
|
|
8
|
+
if (typeof value !== "object" || value === null)
|
|
9
|
+
return false;
|
|
10
|
+
const prototype = Object.getPrototypeOf(value);
|
|
11
|
+
if (prototype !== Object.prototype && prototype !== null)
|
|
12
|
+
return false;
|
|
13
|
+
const keys = Reflect.ownKeys(value);
|
|
14
|
+
if (keys.length !== 1 || keys[0] !== "type")
|
|
15
|
+
return false;
|
|
16
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, "type");
|
|
17
|
+
return descriptor !== undefined && "value" in descriptor && descriptor.value === SKIP_WAITING_MESSAGE.type;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Recognizes only the v1 offline-write request envelopes. It deliberately validates only wire shape: target matching,
|
|
21
|
+
* JSON encoding, length limits and persistence are enforced together by the queue so a future caller cannot mistake
|
|
22
|
+
* a syntactically valid message for an accepted write. Reads never invoke a page-provided accessor.
|
|
23
|
+
*/
|
|
24
|
+
export function isOfflineWriteMessage(value) {
|
|
25
|
+
try {
|
|
26
|
+
const envelope = plainDataObject(value);
|
|
27
|
+
if (envelope === undefined || read(envelope, "version") !== 1 || typeof read(envelope, "requestId") !== "string")
|
|
28
|
+
return false;
|
|
29
|
+
const type = read(envelope, "type");
|
|
30
|
+
if (type === "pwa:offline-write:clear")
|
|
31
|
+
return dataObject(value, ["type", "version", "requestId"]) !== undefined;
|
|
32
|
+
if (type === "pwa:offline-write:flush") {
|
|
33
|
+
const flush = dataObject(value, ["type", "version", "requestId", "sessionBinding"]);
|
|
34
|
+
return flush !== undefined && typeof read(flush, "sessionBinding") === "string";
|
|
35
|
+
}
|
|
36
|
+
if (type !== "pwa:offline-write:enqueue")
|
|
37
|
+
return false;
|
|
38
|
+
const enqueue = dataObject(value, ["type", "version", "requestId", "intent"]);
|
|
39
|
+
if (enqueue === undefined)
|
|
40
|
+
return false;
|
|
41
|
+
const intent = dataObject(read(enqueue, "intent"), ["targetId", "path", "body", "idempotencyKey", "sessionBinding"]);
|
|
42
|
+
return (intent !== undefined &&
|
|
43
|
+
typeof read(intent, "targetId") === "string" &&
|
|
44
|
+
typeof read(intent, "path") === "string" &&
|
|
45
|
+
typeof read(intent, "idempotencyKey") === "string" &&
|
|
46
|
+
typeof read(intent, "sessionBinding") === "string");
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
// Proxies can throw while revealing their prototype or own keys. A hostile message is simply not our protocol.
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/** Matches one closed clear acknowledgement without reading page- or worker-provided accessors. */
|
|
54
|
+
export function isOfflineWriteClearResult(value, requestId) {
|
|
55
|
+
const result = dataObject(value, ["type", "version", "requestId", "status"]);
|
|
56
|
+
return (result !== undefined &&
|
|
57
|
+
read(result, "type") === "pwa:offline-write:result" &&
|
|
58
|
+
read(result, "version") === 1 &&
|
|
59
|
+
read(result, "requestId") === requestId &&
|
|
60
|
+
read(result, "status") === "cleared");
|
|
61
|
+
}
|
|
62
|
+
function dataObject(value, keys) {
|
|
63
|
+
const record = plainDataObject(value);
|
|
64
|
+
if (record === undefined)
|
|
65
|
+
return undefined;
|
|
66
|
+
const actual = Reflect.ownKeys(record);
|
|
67
|
+
if (actual.length !== keys.length || !keys.every((key) => actual.includes(key)))
|
|
68
|
+
return undefined;
|
|
69
|
+
return record;
|
|
70
|
+
}
|
|
71
|
+
function plainDataObject(value) {
|
|
72
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
73
|
+
return undefined;
|
|
74
|
+
const prototype = Object.getPrototypeOf(value);
|
|
75
|
+
if (prototype !== Object.prototype && prototype !== null)
|
|
76
|
+
return undefined;
|
|
77
|
+
const actual = Reflect.ownKeys(value);
|
|
78
|
+
if (actual.some((key) => typeof key !== "string" || !hasDataProperty(value, key)))
|
|
79
|
+
return undefined;
|
|
80
|
+
return value;
|
|
81
|
+
}
|
|
82
|
+
function hasDataProperty(value, key) {
|
|
83
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
84
|
+
return descriptor !== undefined && "value" in descriptor;
|
|
85
|
+
}
|
|
86
|
+
function read(value, key) {
|
|
87
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
88
|
+
return descriptor !== undefined && "value" in descriptor ? descriptor.value : undefined;
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/messages/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/** The platform push payload. `v` is closed at 1; every other field is validated by `checkPushPayload`. */
|
|
2
|
+
export type PwaPushPayload = {
|
|
3
|
+
readonly v: 1;
|
|
4
|
+
/** 1..120 Unicode code points. */
|
|
5
|
+
readonly title: string;
|
|
6
|
+
/** 0..480 Unicode code points. */
|
|
7
|
+
readonly body?: string;
|
|
8
|
+
/** 1..64 Unicode code points. Notifications sharing a tag replace one another. */
|
|
9
|
+
readonly tag?: string;
|
|
10
|
+
/** 1..2048 Unicode code points. Format-level only: the worker resolves and range-checks the target later. */
|
|
11
|
+
readonly url?: string;
|
|
12
|
+
/** 0..256 Unicode code points. Opaque to the platform. */
|
|
13
|
+
readonly data?: string;
|
|
14
|
+
};
|
|
15
|
+
export declare const PUSH_PAYLOAD_VERSION: 1;
|
|
16
|
+
/** UTF-8 byte limit for the whole payload text (Web Push's 4096-byte record limit, less headroom for encryption). */
|
|
17
|
+
export declare const PUSH_PAYLOAD_MAX_BYTES: 3072;
|
|
18
|
+
export declare const PUSH_PAYLOAD_ISSUE_CODES: readonly ["push.payload-too-large", "push.payload-not-json", "push.payload-not-object", "push.payload-unknown-field", "push.payload-version", "push.payload-field-type", "push.payload-field-length"];
|
|
19
|
+
export type PwaPushPayloadIssueCode = (typeof PUSH_PAYLOAD_ISSUE_CODES)[number];
|
|
20
|
+
/** `path` is a JSON pointer into the payload: `""` for the whole payload, `"/title"` for a single field. */
|
|
21
|
+
export type PwaPushPayloadIssue = {
|
|
22
|
+
readonly code: PwaPushPayloadIssueCode;
|
|
23
|
+
readonly path: string;
|
|
24
|
+
};
|
|
25
|
+
export type PwaPushPayloadCheck = {
|
|
26
|
+
readonly ok: true;
|
|
27
|
+
readonly value: PwaPushPayload;
|
|
28
|
+
} | {
|
|
29
|
+
readonly ok: false;
|
|
30
|
+
readonly issues: readonly PwaPushPayloadIssue[];
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Validates an already-parsed value against the payload format. Reports every issue found, in a deterministic
|
|
34
|
+
* order: unknown fields (in the order their keys appear on the object), then the version, then each known field in
|
|
35
|
+
* schema order. Never invokes an accessor property and never includes an input value in an issue. Used directly by
|
|
36
|
+
* the server-side payload builder (a later task); the worker and `checkPushPayloadText` go through this too.
|
|
37
|
+
*/
|
|
38
|
+
export declare function checkPushPayload(value: unknown): PwaPushPayloadCheck;
|
|
39
|
+
/**
|
|
40
|
+
* Validates the raw push text as received by the worker: the UTF-8 byte limit on the text itself, then `JSON.parse`,
|
|
41
|
+
* then `checkPushPayload`. Never throws: a `JSON.parse` failure becomes a `push.payload-not-json` issue.
|
|
42
|
+
*/
|
|
43
|
+
export declare function checkPushPayloadText(text: string): PwaPushPayloadCheck;
|
|
44
|
+
/** Convenience for the worker: the payload, or `null` for anything invalid. */
|
|
45
|
+
export declare function validatePushPayload(text: string): PwaPushPayload | null;
|
|
46
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/push-payload/index.ts"],"names":[],"mappings":"AAKA,2GAA2G;AAC3G,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC;IACd,kCAAkC;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,kCAAkC;IAClC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,kFAAkF;IAClF,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,6GAA6G;IAC7G,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,0DAA0D;IAC1D,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAG,CAAU,CAAC;AAE/C,qHAAqH;AACrH,eAAO,MAAM,sBAAsB,EAAG,IAAa,CAAC;AAEpD,eAAO,MAAM,wBAAwB,uMAQ3B,CAAC;AAEX,MAAM,MAAM,uBAAuB,GAAG,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEhF,4GAA4G;AAC5G,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,CAAC,IAAI,EAAE,uBAAuB,CAAC;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAC3B;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAA;CAAE,GACrD;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,mBAAmB,EAAE,CAAA;CAAE,CAAC;AA0B5E;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,mBAAmB,CAqDpE;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,mBAAmB,CAatE;AAED,+EAA+E;AAC/E,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAGvE"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
// The platform push payload: a closed, zero-dependency format shared by the platform worker (which parses and
|
|
2
|
+
// displays it) and the business backend (which constructs it, via @pwa-platform/push/server's re-export). It imports
|
|
3
|
+
// nothing, so the same validation runs unchanged wherever this entry is bundled. Spec: spec/push-module.md "设计 / 1.
|
|
4
|
+
// 推送格式"; ADR-0021.
|
|
5
|
+
export const PUSH_PAYLOAD_VERSION = 1;
|
|
6
|
+
/** UTF-8 byte limit for the whole payload text (Web Push's 4096-byte record limit, less headroom for encryption). */
|
|
7
|
+
export const PUSH_PAYLOAD_MAX_BYTES = 3072;
|
|
8
|
+
export const PUSH_PAYLOAD_ISSUE_CODES = [
|
|
9
|
+
"push.payload-too-large",
|
|
10
|
+
"push.payload-not-json",
|
|
11
|
+
"push.payload-not-object",
|
|
12
|
+
"push.payload-unknown-field",
|
|
13
|
+
"push.payload-version",
|
|
14
|
+
"push.payload-field-type",
|
|
15
|
+
"push.payload-field-length",
|
|
16
|
+
];
|
|
17
|
+
const FIELD_ORDER = ["title", "body", "tag", "url", "data"];
|
|
18
|
+
const FIELD_LIMITS = {
|
|
19
|
+
title: { required: true, min: 1, max: 120 },
|
|
20
|
+
body: { required: false, min: 0, max: 480 },
|
|
21
|
+
tag: { required: false, min: 1, max: 64 },
|
|
22
|
+
url: { required: false, min: 1, max: 2048 },
|
|
23
|
+
data: { required: false, min: 0, max: 256 },
|
|
24
|
+
};
|
|
25
|
+
const KNOWN_KEYS = new Set(["v", "title", "body", "tag", "url", "data"]);
|
|
26
|
+
/** True only for a data property descriptor: an accessor is never invoked to read its value. */
|
|
27
|
+
function isDataDescriptor(descriptor) {
|
|
28
|
+
return "value" in descriptor;
|
|
29
|
+
}
|
|
30
|
+
/** Unicode code point count, so an astral character (e.g. an emoji) counts once rather than as two UTF-16 units. */
|
|
31
|
+
function codePointLength(text) {
|
|
32
|
+
return [...text].length;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Validates an already-parsed value against the payload format. Reports every issue found, in a deterministic
|
|
36
|
+
* order: unknown fields (in the order their keys appear on the object), then the version, then each known field in
|
|
37
|
+
* schema order. Never invokes an accessor property and never includes an input value in an issue. Used directly by
|
|
38
|
+
* the server-side payload builder (a later task); the worker and `checkPushPayloadText` go through this too.
|
|
39
|
+
*/
|
|
40
|
+
export function checkPushPayload(value) {
|
|
41
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
42
|
+
return { ok: false, issues: [{ code: "push.payload-not-object", path: "" }] };
|
|
43
|
+
}
|
|
44
|
+
const prototype = Object.getPrototypeOf(value);
|
|
45
|
+
if (prototype !== Object.prototype && prototype !== null) {
|
|
46
|
+
return { ok: false, issues: [{ code: "push.payload-not-object", path: "" }] };
|
|
47
|
+
}
|
|
48
|
+
const issues = [];
|
|
49
|
+
for (const key of Reflect.ownKeys(value)) {
|
|
50
|
+
if (!KNOWN_KEYS.has(key))
|
|
51
|
+
issues.push({ code: "push.payload-unknown-field", path: "" });
|
|
52
|
+
}
|
|
53
|
+
const versionDescriptor = Object.getOwnPropertyDescriptor(value, "v");
|
|
54
|
+
if (versionDescriptor === undefined || !isDataDescriptor(versionDescriptor) || versionDescriptor.value !== PUSH_PAYLOAD_VERSION) {
|
|
55
|
+
issues.push({ code: "push.payload-version", path: "/v" });
|
|
56
|
+
}
|
|
57
|
+
const fields = {};
|
|
58
|
+
for (const field of FIELD_ORDER) {
|
|
59
|
+
const limit = FIELD_LIMITS[field];
|
|
60
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, field);
|
|
61
|
+
if (descriptor === undefined) {
|
|
62
|
+
if (limit.required)
|
|
63
|
+
issues.push({ code: "push.payload-field-type", path: `/${field}` });
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
if (!isDataDescriptor(descriptor) || typeof descriptor.value !== "string") {
|
|
67
|
+
issues.push({ code: "push.payload-field-type", path: `/${field}` });
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
const fieldValue = descriptor.value;
|
|
71
|
+
const length = codePointLength(fieldValue);
|
|
72
|
+
if (length < limit.min || length > limit.max) {
|
|
73
|
+
issues.push({ code: "push.payload-field-length", path: `/${field}` });
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
fields[field] = fieldValue;
|
|
77
|
+
}
|
|
78
|
+
if (issues.length > 0)
|
|
79
|
+
return { ok: false, issues };
|
|
80
|
+
// `title` is required; with no issues collected, its required-field and type checks above must have passed, so a
|
|
81
|
+
// value was recorded. (No throw: this module never throws, for any input.)
|
|
82
|
+
const payload = { title: fields.title };
|
|
83
|
+
if (fields.body !== undefined)
|
|
84
|
+
payload.body = fields.body;
|
|
85
|
+
if (fields.tag !== undefined)
|
|
86
|
+
payload.tag = fields.tag;
|
|
87
|
+
if (fields.url !== undefined)
|
|
88
|
+
payload.url = fields.url;
|
|
89
|
+
if (fields.data !== undefined)
|
|
90
|
+
payload.data = fields.data;
|
|
91
|
+
return { ok: true, value: Object.freeze({ v: PUSH_PAYLOAD_VERSION, ...payload }) };
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Validates the raw push text as received by the worker: the UTF-8 byte limit on the text itself, then `JSON.parse`,
|
|
95
|
+
* then `checkPushPayload`. Never throws: a `JSON.parse` failure becomes a `push.payload-not-json` issue.
|
|
96
|
+
*/
|
|
97
|
+
export function checkPushPayloadText(text) {
|
|
98
|
+
if (new TextEncoder().encode(text).length > PUSH_PAYLOAD_MAX_BYTES) {
|
|
99
|
+
return { ok: false, issues: [{ code: "push.payload-too-large", path: "" }] };
|
|
100
|
+
}
|
|
101
|
+
let parsed;
|
|
102
|
+
try {
|
|
103
|
+
parsed = JSON.parse(text);
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
return { ok: false, issues: [{ code: "push.payload-not-json", path: "" }] };
|
|
107
|
+
}
|
|
108
|
+
return checkPushPayload(parsed);
|
|
109
|
+
}
|
|
110
|
+
/** Convenience for the worker: the payload, or `null` for anything invalid. */
|
|
111
|
+
export function validatePushPayload(text) {
|
|
112
|
+
const result = checkPushPayloadText(text);
|
|
113
|
+
return result.ok ? result.value : null;
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/push-payload/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type PwaRecoveryWorkerConfig } from "../shared/config.js";
|
|
2
|
+
export type PwaRecoveryWorkerOptions = {
|
|
3
|
+
readonly scope: ServiceWorkerGlobalScope;
|
|
4
|
+
/** The injected recovery config; validated before any listener is registered. */
|
|
5
|
+
readonly config: PwaRecoveryWorkerConfig;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Registers the recovery worker (ADR-0005): it takes over immediately only after it removes every cache and the
|
|
9
|
+
* identity-derived offline-write database of this app in this environment, then serves nothing, so page requests go
|
|
10
|
+
* straight to the network. On activation it also cancels this registration's push subscription, after deletion and
|
|
11
|
+
* before claiming clients, so the business backend starts seeing failed sends and can clean up (ADR-0021, "对
|
|
12
|
+
* ADR-0012 的修订").
|
|
13
|
+
*
|
|
14
|
+
* It registers only `install` and `activate`; it never registers `fetch`, `push` or `notificationclick`, never opens
|
|
15
|
+
* a cache and never deletes a cache outside `config.appCachePrefix`.
|
|
16
|
+
*/
|
|
17
|
+
export declare function registerRecoveryWorker({ scope, config }: PwaRecoveryWorkerOptions): void;
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/recovery-worker/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAgC,KAAK,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAEjG,MAAM,MAAM,wBAAwB,GAAG;IACrC,QAAQ,CAAC,KAAK,EAAE,wBAAwB,CAAC;IACzC,iFAAiF;IACjF,QAAQ,CAAC,MAAM,EAAE,uBAAuB,CAAC;CAC1C,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,wBAAwB,GAAG,IAAI,CAWxF"}
|