@graview/guest 0.1.6 → 0.1.8

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.
Files changed (70) hide show
  1. package/README.md +86 -0
  2. package/dist/build.d.ts +43 -0
  3. package/dist/build.d.ts.map +1 -0
  4. package/dist/build.js +117 -0
  5. package/dist/build.js.map +1 -0
  6. package/dist/channel.d.ts +51 -0
  7. package/dist/channel.d.ts.map +1 -0
  8. package/dist/channel.js +105 -0
  9. package/dist/channel.js.map +1 -0
  10. package/dist/guest.d.ts +2 -22
  11. package/dist/guest.d.ts.map +1 -1
  12. package/dist/guest.js +8 -89
  13. package/dist/guest.js.map +1 -1
  14. package/dist/host/frame.d.ts.map +1 -1
  15. package/dist/host/frame.js +1 -6
  16. package/dist/host/frame.js.map +1 -1
  17. package/dist/host/index.d.ts +3 -0
  18. package/dist/host/index.d.ts.map +1 -1
  19. package/dist/host/index.js.map +1 -1
  20. package/dist/host/kit.d.ts +85 -0
  21. package/dist/host/kit.d.ts.map +1 -0
  22. package/dist/host/kit.js +344 -0
  23. package/dist/host/kit.js.map +1 -0
  24. package/dist/host/nonce.d.ts +3 -0
  25. package/dist/host/nonce.d.ts.map +1 -0
  26. package/dist/host/nonce.js +7 -0
  27. package/dist/host/nonce.js.map +1 -0
  28. package/dist/host/react.d.ts +16 -5
  29. package/dist/host/react.d.ts.map +1 -1
  30. package/dist/host/react.js +31 -3
  31. package/dist/host/react.js.map +1 -1
  32. package/dist/host/session.d.ts +6 -0
  33. package/dist/host/session.d.ts.map +1 -1
  34. package/dist/host/session.js +4 -0
  35. package/dist/host/session.js.map +1 -1
  36. package/dist/host/worker.d.ts +96 -0
  37. package/dist/host/worker.d.ts.map +1 -0
  38. package/dist/host/worker.js +195 -0
  39. package/dist/host/worker.js.map +1 -0
  40. package/dist/index.d.ts +1 -1
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/kit.d.ts +202 -0
  43. package/dist/kit.d.ts.map +1 -0
  44. package/dist/kit.js +69 -0
  45. package/dist/kit.js.map +1 -0
  46. package/dist/protocol.d.ts +48 -1
  47. package/dist/protocol.d.ts.map +1 -1
  48. package/dist/protocol.js +20 -0
  49. package/dist/protocol.js.map +1 -1
  50. package/dist/worker/elements.d.ts +11 -0
  51. package/dist/worker/elements.d.ts.map +1 -0
  52. package/dist/worker/elements.js +28 -0
  53. package/dist/worker/elements.js.map +1 -0
  54. package/dist/worker/harden.d.ts +39 -0
  55. package/dist/worker/harden.d.ts.map +1 -0
  56. package/dist/worker/harden.js +175 -0
  57. package/dist/worker/harden.js.map +1 -0
  58. package/dist/worker/index.d.ts +32 -0
  59. package/dist/worker/index.d.ts.map +1 -0
  60. package/dist/worker/index.js +92 -0
  61. package/dist/worker/index.js.map +1 -0
  62. package/dist/worker/listeners.d.ts +19 -0
  63. package/dist/worker/listeners.d.ts.map +1 -0
  64. package/dist/worker/listeners.js +157 -0
  65. package/dist/worker/listeners.js.map +1 -0
  66. package/dist/worker/natives.d.ts +7 -0
  67. package/dist/worker/natives.d.ts.map +1 -0
  68. package/dist/worker/natives.js +12 -0
  69. package/dist/worker/natives.js.map +1 -0
  70. package/package.json +30 -7
package/dist/kit.js ADDED
@@ -0,0 +1,69 @@
1
+ /**
2
+ * THE COMPONENT KIT A WORKER GUEST DRAWS WITH (FR-69), declared once.
3
+ *
4
+ * A guest in a worker has no DOM of its own: it builds a tree of these
5
+ * elements with Remote DOM, and the host draws it in its own document. The
6
+ * kit is Tier 1's closed set of blocks (FR-03: title, text, badge, field,
7
+ * progress, group, divider), plus the few a view that asks for acts needs —
8
+ * a card to hold them, a button, an input, and a link.
9
+ *
10
+ * Each component says, once, its typed properties and its events. The
11
+ * worker side defines one `RemoteElement` per component from it
12
+ * (worker/elements.ts), and the host side draws from it (host/kit.ts): only
13
+ * a component in the kit, only a property or event it declares, only a
14
+ * value of the declared type, and a `url` only when it is `https:`. Adding
15
+ * a property here makes it a property on both sides; nothing else changes.
16
+ *
17
+ * This module has no imports: a guest bundle carries it and nothing of the
18
+ * framework.
19
+ */
20
+ /** The tones a block may take: FR-03's own (`VIEW_TONES` in @graview/core/document, held to it by a test). */
21
+ export const KIT_TONES = ["good", "warn", "bad", "neutral", "accent"];
22
+ /**
23
+ * The host attributes a property may be drawn as, besides the default
24
+ * `data-gv-<name>`. A closed list: never an event handler, a style, a
25
+ * source or a frame.
26
+ */
27
+ export const KIT_HOST_ATTRIBUTES = ["value", "max", "aria-label", "placeholder", "disabled"];
28
+ /** The DOM events a kit event may come from, on the element the host drew. */
29
+ export const KIT_HOST_EVENTS = ["click", "change"];
30
+ /**
31
+ * Where a link may open. A new tab (`_blank`) unless the kit says
32
+ * otherwise; never `_top` or `_parent`, which would take the host's page.
33
+ */
34
+ export const KIT_LINK_TARGETS = ["_blank", "_self"];
35
+ /** The host elements a component may be drawn as. */
36
+ export const KIT_HOST_TAGS = ["section", "div", "span", "strong", "p", "hr", "a", "button", "input", "progress"];
37
+ const tone = { type: { oneOf: KIT_TONES } };
38
+ /** The kit, by element name. Every name starts `gv-`. */
39
+ export const GUEST_KIT = {
40
+ "gv-card": { host: "section", properties: { tone }, events: {}, children: "any" },
41
+ "gv-group": { host: "div", properties: { direction: { type: { oneOf: ["row", "column"] } } }, events: {}, children: "any" },
42
+ "gv-title": { host: "strong", properties: {}, events: {}, children: "text" },
43
+ "gv-text": { host: "p", properties: { tone }, events: {}, children: "text" },
44
+ "gv-badge": { host: "span", properties: { tone }, events: {}, children: "text" },
45
+ "gv-field": { host: "div", properties: { label: { type: "string" } }, events: {}, children: "text" },
46
+ "gv-progress": {
47
+ host: "progress",
48
+ properties: { value: { type: "number", as: "value" }, max: { type: "number", as: "max" }, label: { type: "string", as: "aria-label" } },
49
+ events: {},
50
+ children: "none",
51
+ },
52
+ "gv-divider": { host: "hr", properties: {}, events: {}, children: "none" },
53
+ "gv-link": { host: "a", properties: { href: { type: "url" } }, events: {}, children: "text" },
54
+ "gv-button": {
55
+ host: "button",
56
+ properties: { tone, disabled: { type: "boolean", as: "disabled" } },
57
+ events: { press: { from: "click" } },
58
+ children: "text",
59
+ },
60
+ "gv-input": {
61
+ host: "input",
62
+ properties: { label: { type: "string", as: "aria-label" }, value: { type: "string", as: "value" }, placeholder: { type: "string", as: "placeholder" } },
63
+ events: { change: { from: "change", detail: "value" } },
64
+ children: "none",
65
+ },
66
+ };
67
+ /** The longest text a kit node may hold, in characters; longer is cut. */
68
+ export const KIT_MAX_TEXT = 10_000;
69
+ //# sourceMappingURL=kit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kit.js","sourceRoot":"","sources":["../src/kit.ts"],"names":[],"mappings":"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"}
@@ -15,6 +15,26 @@
15
15
  * guest → host { type: "size", nonce, height } (over the port: the height it wants)
16
16
  * host → guest { type: "answer", id, ok, … } (over the port: what became of an act)
17
17
  *
18
+ * A GUEST IN A WORKER (FR-68) says the same things. Its `guest-ready` goes
19
+ * to the worker's owner (`self.postMessage`), which is the host by
20
+ * construction, and the hello comes back the same way with the port. A
21
+ * worker has no DOM of its own to draw in, so it draws in the host's, from
22
+ * the component kit alone (kit.ts):
23
+ *
24
+ * guest → host { type: "render", nonce, records } (over the port: Remote DOM mutation records)
25
+ * host → guest { type: "event", listener, detail } (over the port: a kit event the viewer raised)
26
+ *
27
+ * A frame guest never sends `render`; a host that is not drawing a worker
28
+ * drops it unread.
29
+ *
30
+ * A worker's host also watches that the worker is alive. Its runtime — not
31
+ * the guest's code, which can stop it only by blocking its own event loop —
32
+ * answers each heartbeat with the beat it was asked, and a worker that goes
33
+ * `limits.silentMs` without an answer is stopped:
34
+ *
35
+ * host → guest { type: "heartbeat", beat } (over the port, on an interval)
36
+ * guest → host { type: "heartbeat", nonce, beat } (over the port: the runtime's answer)
37
+ *
18
38
  * The host answers a `guest-ready` only from its own frame's window and
19
39
  * only from the opaque origin, and every request over the port carries the
20
40
  * nonce of that hello. What the guest is pushed is the store as the viewer
@@ -112,10 +132,25 @@ export interface HostHello {
112
132
  readonly nonce: string;
113
133
  readonly view: string;
114
134
  }
135
+ /**
136
+ * A kit event the viewer raised on something a worker guest drew: which of
137
+ * the guest's listeners to call, and the one plain value the kit declares
138
+ * for it (an input's text), if any.
139
+ */
140
+ export interface GuestEvent {
141
+ readonly type: "event";
142
+ readonly listener: number;
143
+ readonly detail?: string | number | boolean | null;
144
+ }
145
+ /** The host asking a worker guest's runtime whether it is still answering. */
146
+ export interface HostHeartbeat {
147
+ readonly type: "heartbeat";
148
+ readonly beat: number;
149
+ }
115
150
  export type HostMessage = {
116
151
  readonly type: "props";
117
152
  readonly props: GuestProps;
118
- } | GuestAnswer;
153
+ } | GuestAnswer | GuestEvent | HostHeartbeat;
119
154
  export type GuestRequest = {
120
155
  readonly type: "act";
121
156
  readonly nonce: string;
@@ -130,6 +165,18 @@ export type GuestRequest = {
130
165
  readonly type: "size";
131
166
  readonly nonce: string;
132
167
  readonly height: number;
168
+ }
169
+ /** A worker guest's drawing: Remote DOM mutation records, with each listener sent as `{ listener: id }`. */
170
+ | {
171
+ readonly type: "render";
172
+ readonly nonce: string;
173
+ readonly records: readonly unknown[];
174
+ }
175
+ /** The runtime's answer to a heartbeat, with the beat it was asked. */
176
+ | {
177
+ readonly type: "heartbeat";
178
+ readonly nonce: string;
179
+ readonly beat: number;
133
180
  };
134
181
  /** Whether a window message is a guest saying it is ready. */
135
182
  export declare function isGuestReady(data: unknown): data is GuestReady;
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"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"}
package/dist/protocol.js CHANGED
@@ -15,6 +15,26 @@
15
15
  * guest → host { type: "size", nonce, height } (over the port: the height it wants)
16
16
  * host → guest { type: "answer", id, ok, … } (over the port: what became of an act)
17
17
  *
18
+ * A GUEST IN A WORKER (FR-68) says the same things. Its `guest-ready` goes
19
+ * to the worker's owner (`self.postMessage`), which is the host by
20
+ * construction, and the hello comes back the same way with the port. A
21
+ * worker has no DOM of its own to draw in, so it draws in the host's, from
22
+ * the component kit alone (kit.ts):
23
+ *
24
+ * guest → host { type: "render", nonce, records } (over the port: Remote DOM mutation records)
25
+ * host → guest { type: "event", listener, detail } (over the port: a kit event the viewer raised)
26
+ *
27
+ * A frame guest never sends `render`; a host that is not drawing a worker
28
+ * drops it unread.
29
+ *
30
+ * A worker's host also watches that the worker is alive. Its runtime — not
31
+ * the guest's code, which can stop it only by blocking its own event loop —
32
+ * answers each heartbeat with the beat it was asked, and a worker that goes
33
+ * `limits.silentMs` without an answer is stopped:
34
+ *
35
+ * host → guest { type: "heartbeat", beat } (over the port, on an interval)
36
+ * guest → host { type: "heartbeat", nonce, beat } (over the port: the runtime's answer)
37
+ *
18
38
  * The host answers a `guest-ready` only from its own frame's window and
19
39
  * only from the opaque origin, and every request over the port carries the
20
40
  * nonce of that hello. What the guest is pushed is the store as the viewer
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,gFAAgF;AAChF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC;AAEhC,gFAAgF;AAChF,MAAM,CAAC,MAAM,aAAa,GAAG,eAAe,CAAC;AAE7C,2EAA2E;AAC3E,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC;AAuFpC,8DAA8D;AAC9D,MAAM,UAAU,YAAY,CAAC,IAAa;IACxC,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,IAAK,IAAmB,CAAC,OAAO,KAAK,aAAa,CAAC;AACrG,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,WAAW,CAAC,IAAa;IACvC,MAAM,KAAK,GAAG,IAAiB,CAAC;IAChC,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,KAAK,YAAY,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC;AACxH,CAAC"}
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAEH,gFAAgF;AAChF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC;AAEhC,gFAAgF;AAChF,MAAM,CAAC,MAAM,aAAa,GAAG,eAAe,CAAC;AAE7C,2EAA2E;AAC3E,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC;AA4GpC,8DAA8D;AAC9D,MAAM,UAAU,YAAY,CAAC,IAAa;IACxC,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,IAAK,IAAmB,CAAC,OAAO,KAAK,aAAa,CAAC;AACrG,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,WAAW,CAAC,IAAa;IACvC,MAAM,KAAK,GAAG,IAAiB,CAAC;IAChC,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,KAAK,YAAY,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC;AACxH,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { Kit, KitComponent } from "../kit.js";
2
+ /**
3
+ * ONE COMPONENT OF THE KIT, AS A REMOTE ELEMENT: its declared properties
4
+ * (each also settable as an attribute of the same name) and its declared
5
+ * events, and nothing else. What it says goes to the host as mutation
6
+ * records, and the host draws only what the same declaration allows.
7
+ */
8
+ export declare function kitElement(component: KitComponent): CustomElementConstructor;
9
+ /** Define every component of a kit in a registry, by its element name. */
10
+ export declare function defineKit(kit: Kit, registry?: CustomElementRegistry): void;
11
+ //# sourceMappingURL=elements.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"elements.d.ts","sourceRoot":"","sources":["../../src/worker/elements.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,YAAY,EAAmB,MAAM,WAAW,CAAC;AAKpE;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,YAAY,GAAG,wBAAwB,CAU5E;AAED,0EAA0E;AAC1E,wBAAgB,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,GAAE,qBAAsC,GAAG,IAAI,CAI1F"}
@@ -0,0 +1,28 @@
1
+ import { RemoteElement } from "@remote-dom/core/elements";
2
+ /** The Remote DOM type a kit property is kept as on the worker's side. */
3
+ const remoteType = (type) => (type === "number" ? Number : type === "boolean" ? Boolean : String);
4
+ /**
5
+ * ONE COMPONENT OF THE KIT, AS A REMOTE ELEMENT: its declared properties
6
+ * (each also settable as an attribute of the same name) and its declared
7
+ * events, and nothing else. What it says goes to the host as mutation
8
+ * records, and the host draws only what the same declaration allows.
9
+ */
10
+ export function kitElement(component) {
11
+ const properties = Object.fromEntries(Object.entries(component.properties).map(([name, property]) => [name, { type: remoteType(property.type), attribute: true }]));
12
+ const events = Object.keys(component.events);
13
+ class KitElement extends RemoteElement {
14
+ /* A kit element is never slotted: the host has no slots to put it in. */
15
+ static slottable = false;
16
+ static remoteProperties = properties;
17
+ static remoteEvents = events;
18
+ }
19
+ return KitElement;
20
+ }
21
+ /** Define every component of a kit in a registry, by its element name. */
22
+ export function defineKit(kit, registry = customElements) {
23
+ for (const [name, component] of Object.entries(kit)) {
24
+ if (!registry.get(name))
25
+ registry.define(name, kitElement(component));
26
+ }
27
+ }
28
+ //# sourceMappingURL=elements.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"elements.js","sourceRoot":"","sources":["../../src/worker/elements.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAG1D,0EAA0E;AAC1E,MAAM,UAAU,GAAG,CAAC,IAAqB,EAAE,EAAE,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;AAEnH;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,SAAuB;IAChD,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACpK,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAC7C,MAAM,UAAW,SAAQ,aAAa;QACpC,yEAAyE;QACzE,MAAM,CAAmB,SAAS,GAAG,KAAc,CAAC;QACpD,MAAM,CAAmB,gBAAgB,GAAG,UAAU,CAAC;QACvD,MAAM,CAAmB,YAAY,GAAG,MAAM,CAAC;;IAEjD,OAAO,UAAiD,CAAC;AAC3D,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,SAAS,CAAC,GAAQ,EAAE,WAAkC,cAAc;IAClF,KAAK,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACpD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;IACxE,CAAC;AACH,CAAC"}
@@ -0,0 +1,39 @@
1
+ /** The language's own globals: ECMAScript, ES2025 and the proposals engines already ship. */
2
+ export declare const LANGUAGE: readonly ["globalThis", "Infinity", "NaN", "undefined", "isFinite", "isNaN", "parseFloat", "parseInt", "decodeURI", "decodeURIComponent", "encodeURI", "encodeURIComponent", "escape", "unescape", "Object", "Function", "Array", "Number", "Boolean", "String", "Symbol", "BigInt", "Date", "Promise", "RegExp", "Math", "JSON", "Reflect", "Proxy", "Intl", "Error", "AggregateError", "EvalError", "RangeError", "ReferenceError", "SyntaxError", "TypeError", "URIError", "SuppressedError", "Map", "Set", "WeakMap", "WeakSet", "WeakRef", "FinalizationRegistry", "Iterator", "AsyncIterator", "DisposableStack", "AsyncDisposableStack", "ArrayBuffer", "SharedArrayBuffer", "DataView", "Atomics", "Int8Array", "Uint8Array", "Uint8ClampedArray", "Int16Array", "Uint16Array", "Int32Array", "Uint32Array", "Float16Array", "Float32Array", "Float64Array", "BigInt64Array", "BigUint64Array"];
3
+ /** What Remote DOM's polyfill puts on the global: a document to build in, and the classes of what it builds. */
4
+ export declare const POLYFILLED_DOM: readonly ["window", "parent", "top", "document", "customElements", "Event", "ErrorEvent", "PromiseRejectionEvent", "ToggleEvent", "FocusEvent", "ClipboardEvent", "CustomEvent", "EventTarget", "Node", "ParentNode", "ChildNode", "DocumentFragment", "Document", "CharacterData", "Comment", "Text", "Element", "HTMLElement", "SVGElement", "HTMLTemplateElement", "MutationObserver"];
5
+ /** The platform's few that stay (see the top of this module for why each). */
6
+ export declare const PLATFORM: readonly ["self", "postMessage", "setTimeout", "clearTimeout", "setInterval", "clearInterval", "queueMicrotask", "structuredClone", "crypto", "console", "DOMException"];
7
+ /**
8
+ * Numbers an engine will not let go: Chromium's worker global defines
9
+ * `TEMPORARY` (0) and `PERSISTENT` (1), the constants of the FileSystem API
10
+ * it no longer ships, as non-configurable. They are numbers and hand back
11
+ * nothing, so they may stay — only while they are numbers; anything else
12
+ * by these names is removed or stops the worker.
13
+ */
14
+ export declare const INERT: readonly ["TEMPORARY", "PERSISTENT"];
15
+ /**
16
+ * EVERY NAME A GUEST'S WORKER GLOBAL MAY HAVE, on the global or any
17
+ * prototype on its chain before `Object.prototype` (where a prototype's
18
+ * `constructor` and `Symbol.toStringTag` stay too). Anything else is
19
+ * removed before the guest runs.
20
+ */
21
+ export declare const GUEST_GLOBALS: readonly string[];
22
+ /** What `Object.prototype` holds in every engine; it is the language's, and the walk does not touch it. */
23
+ export declare const OBJECT_PROTOTYPE: readonly string[];
24
+ /** What hardening did: every name it took, and any it could not. */
25
+ export interface Hardening {
26
+ readonly removed: readonly string[];
27
+ /** Names outside the allowlist that could not be removed. Empty, or the worker is not hardened. */
28
+ readonly stuck: readonly string[];
29
+ /** Whether the global takes no new names. Where the engine refuses, a guest can add its own, which reach nothing removed. */
30
+ readonly sealed: boolean;
31
+ /** False when the runtime is not in a worker, and so hardened nothing. */
32
+ readonly worker?: false;
33
+ }
34
+ /**
35
+ * HARDEN A WORKER'S GLOBAL before guest code runs. Called once by the
36
+ * worker entry, after Remote DOM's polyfill and the kit are in place.
37
+ */
38
+ export declare function harden(scope?: typeof globalThis): Hardening;
39
+ //# sourceMappingURL=harden.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harden.d.ts","sourceRoot":"","sources":["../../src/worker/harden.ts"],"names":[],"mappings":"AA0CA,6FAA6F;AAC7F,eAAO,MAAM,QAAQ,y2BAQX,CAAC;AAEX,gHAAgH;AAChH,eAAO,MAAM,cAAc,2XAIjB,CAAC;AAEX,8EAA8E;AAC9E,eAAO,MAAM,QAAQ,0KAA2K,CAAC;AAEjM;;;;;;GAMG;AACH,eAAO,MAAM,KAAK,sCAAuC,CAAC;AAE1D;;;;;GAKG;AACH,eAAO,MAAM,aAAa,EAAE,SAAS,MAAM,EAA2E,CAAC;AAEvH,2GAA2G;AAC3G,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAG5C,CAAC;AAEH,oEAAoE;AACpE,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,mGAAmG;IACnG,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,6HAA6H;IAC7H,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,0EAA0E;IAC1E,QAAQ,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC;CACzB;AAID;;;GAGG;AACH,wBAAgB,MAAM,CAAC,KAAK,GAAE,OAAO,UAAuB,GAAG,SAAS,CAoFvE"}
@@ -0,0 +1,175 @@
1
+ /*
2
+ * A HARDENED WORKER (FR-70).
3
+ *
4
+ * A worker's policy and origin are the host's to set, and on ChatGPT the
5
+ * origin is shared by every widget an app's connector shows: Graview
6
+ * Cloud's spike watched one view's worker plant IndexedDB and Cache Storage
7
+ * data that a second view's worker read, and ChatGPT's `connect-src` always
8
+ * names a list of public CDNs. So before any guest code runs, the runtime
9
+ * takes from the worker's global everything outside a short allowlist —
10
+ * the network, storage, channels, nested workers, more code — from the
11
+ * global itself and from every prototype on its chain, so no reference is
12
+ * left to recover them by, and makes what is left stay as it is.
13
+ *
14
+ * What stays, and why:
15
+ *
16
+ * the language Object, Array, Promise, JSON, Intl, the typed arrays, … (LANGUAGE)
17
+ * postMessage it reaches only the worker's owner, the host, which drops all but one ready
18
+ * timers setTimeout and setInterval refuse a string, which would be code from text
19
+ * queueMicrotask, structuredClone
20
+ * crypto as an object with getRandomValues alone
21
+ * console it reaches the developer's tools, nothing else; a guest's errors stay readable
22
+ * DOMException an error class, which the polyfill throws
23
+ * the polyfilled DOM Remote DOM's document, window and node classes (POLYFILLED_DOM)
24
+ *
25
+ * And what goes that a reader might expect to stay:
26
+ *
27
+ * eval, Function code from text could write `import()`, which no global's removal can take
28
+ * away and which reaches every origin script-src allows (ChatGPT's CDNs, or in
29
+ * WebKit under Claude's policy any https origin). Without them a guest's code is
30
+ * the bundle it was built as, and the build refuses one with `import()` in it
31
+ * (FR-71). `Function` stays as a name, for `instanceof`, but makes nothing, and
32
+ * so do the async and generator function constructors.
33
+ * performance a fine clock, which is a side channel and draws nothing
34
+ * addEventListener, onmessage, onerror, close, name, location, navigator, self.fonts, WebAssembly, …
35
+ *
36
+ * The removal is deletion in the same realm, so it holds only while no
37
+ * remaining API can hand back what was removed. The allowlist is what keeps
38
+ * that true as browsers add APIs: a name not on it goes, whatever it is.
39
+ * `scripts/guest-sandbox.mjs` enumerates the worker's global in Chromium and
40
+ * WebKit and fails on any name outside it, and tries the ways back.
41
+ */
42
+ /** The language's own globals: ECMAScript, ES2025 and the proposals engines already ship. */
43
+ export const LANGUAGE = [
44
+ "globalThis", "Infinity", "NaN", "undefined", "isFinite", "isNaN", "parseFloat", "parseInt",
45
+ "decodeURI", "decodeURIComponent", "encodeURI", "encodeURIComponent", "escape", "unescape",
46
+ "Object", "Function", "Array", "Number", "Boolean", "String", "Symbol", "BigInt", "Date", "Promise", "RegExp", "Math", "JSON", "Reflect", "Proxy", "Intl",
47
+ "Error", "AggregateError", "EvalError", "RangeError", "ReferenceError", "SyntaxError", "TypeError", "URIError", "SuppressedError",
48
+ "Map", "Set", "WeakMap", "WeakSet", "WeakRef", "FinalizationRegistry", "Iterator", "AsyncIterator", "DisposableStack", "AsyncDisposableStack",
49
+ "ArrayBuffer", "SharedArrayBuffer", "DataView", "Atomics",
50
+ "Int8Array", "Uint8Array", "Uint8ClampedArray", "Int16Array", "Uint16Array", "Int32Array", "Uint32Array", "Float16Array", "Float32Array", "Float64Array", "BigInt64Array", "BigUint64Array",
51
+ ];
52
+ /** What Remote DOM's polyfill puts on the global: a document to build in, and the classes of what it builds. */
53
+ export const POLYFILLED_DOM = [
54
+ "window", "parent", "top", "document", "customElements",
55
+ "Event", "ErrorEvent", "PromiseRejectionEvent", "ToggleEvent", "FocusEvent", "ClipboardEvent", "CustomEvent", "EventTarget",
56
+ "Node", "ParentNode", "ChildNode", "DocumentFragment", "Document", "CharacterData", "Comment", "Text", "Element", "HTMLElement", "SVGElement", "HTMLTemplateElement", "MutationObserver",
57
+ ];
58
+ /** The platform's few that stay (see the top of this module for why each). */
59
+ export const PLATFORM = ["self", "postMessage", "setTimeout", "clearTimeout", "setInterval", "clearInterval", "queueMicrotask", "structuredClone", "crypto", "console", "DOMException"];
60
+ /**
61
+ * Numbers an engine will not let go: Chromium's worker global defines
62
+ * `TEMPORARY` (0) and `PERSISTENT` (1), the constants of the FileSystem API
63
+ * it no longer ships, as non-configurable. They are numbers and hand back
64
+ * nothing, so they may stay — only while they are numbers; anything else
65
+ * by these names is removed or stops the worker.
66
+ */
67
+ export const INERT = ["TEMPORARY", "PERSISTENT"];
68
+ /**
69
+ * EVERY NAME A GUEST'S WORKER GLOBAL MAY HAVE, on the global or any
70
+ * prototype on its chain before `Object.prototype` (where a prototype's
71
+ * `constructor` and `Symbol.toStringTag` stay too). Anything else is
72
+ * removed before the guest runs.
73
+ */
74
+ export const GUEST_GLOBALS = Object.freeze([...LANGUAGE, ...POLYFILLED_DOM, ...PLATFORM, ...INERT]);
75
+ /** What `Object.prototype` holds in every engine; it is the language's, and the walk does not touch it. */
76
+ export const OBJECT_PROTOTYPE = Object.freeze([
77
+ "constructor", "__defineGetter__", "__defineSetter__", "hasOwnProperty", "__lookupGetter__", "__lookupSetter__",
78
+ "isPrototypeOf", "propertyIsEnumerable", "toString", "valueOf", "__proto__", "toLocaleString",
79
+ ]);
80
+ const nameOf = (key) => (typeof key === "symbol" ? `[${key.description ?? "symbol"}]` : key);
81
+ /**
82
+ * HARDEN A WORKER'S GLOBAL before guest code runs. Called once by the
83
+ * worker entry, after Remote DOM's polyfill and the kit are in place.
84
+ */
85
+ export function harden(scope = globalThis) {
86
+ const removed = [];
87
+ const stuck = [];
88
+ const allowed = new Set([...LANGUAGE, ...POLYFILLED_DOM, ...PLATFORM, "constructor", Symbol.toStringTag]);
89
+ /* A name on the inert list stays only if it will not go and holds a number that cannot be changed. */
90
+ const inert = (at, key) => {
91
+ const descriptor = Reflect.getOwnPropertyDescriptor(at, key);
92
+ return INERT.includes(key) && descriptor !== undefined && "value" in descriptor && typeof descriptor.value === "number" && !descriptor.writable && !descriptor.configurable;
93
+ };
94
+ const global = scope;
95
+ /* Kept, but narrowed: what the guest is handed in place of the platform's own. */
96
+ const nativeSetTimeout = global["setTimeout"];
97
+ const nativeSetInterval = global["setInterval"];
98
+ const nativeCrypto = global["crypto"];
99
+ const timer = (native, name) => function (handler, ms, ...args) {
100
+ if (typeof handler !== "function")
101
+ throw new TypeError(`${name} takes a function: a guest view cannot run code from text`);
102
+ return native.call(scope, handler, ms, ...args);
103
+ };
104
+ const crypto = nativeCrypto ? Object.freeze({ getRandomValues: (array) => nativeCrypto.getRandomValues(array) }) : undefined;
105
+ /*
106
+ * THE POLYFILL'S WINDOW. Remote DOM's `window` (and `document.defaultView`)
107
+ * is an object of its own, which took the platform's `navigator` and
108
+ * `location` when it was made; they go from it as from the global.
109
+ */
110
+ const view = global["document"]?.defaultView;
111
+ if (view && view !== global) {
112
+ for (const key of Reflect.ownKeys(view)) {
113
+ if (typeof key === "symbol" || allowed.has(key))
114
+ continue;
115
+ if (!Reflect.deleteProperty(view, key))
116
+ stuck.push(`window.${key}`);
117
+ }
118
+ }
119
+ /* THE CHAIN: the global, and every prototype up to Object.prototype. */
120
+ const chain = [];
121
+ for (let at = scope; at && at !== Object.prototype; at = Object.getPrototypeOf(at))
122
+ chain.push(at);
123
+ for (const at of chain) {
124
+ for (const key of Reflect.ownKeys(at)) {
125
+ if (allowed.has(key))
126
+ continue;
127
+ if (Reflect.deleteProperty(at, key))
128
+ removed.push(nameOf(key));
129
+ else if (!inert(at, key))
130
+ stuck.push(nameOf(key));
131
+ }
132
+ }
133
+ /* CODE FROM TEXT: eval went with the rest; every function constructor now refuses. */
134
+ const refuse = () => function Function() {
135
+ throw new EvalError("A guest view cannot make code from text.");
136
+ };
137
+ const prototypes = [Function.prototype, Object.getPrototypeOf(async function () { }), Object.getPrototypeOf(function* () { }), Object.getPrototypeOf(async function* () { })];
138
+ for (const prototype of prototypes) {
139
+ const stand = refuse();
140
+ Object.defineProperty(stand, "prototype", { value: prototype, writable: false, enumerable: false, configurable: false });
141
+ if (!Reflect.defineProperty(prototype, "constructor", { value: stand, writable: false, enumerable: false, configurable: false }))
142
+ stuck.push("Function.prototype.constructor");
143
+ if (prototype === Function.prototype)
144
+ Reflect.defineProperty(scope, "Function", { value: stand, writable: true, enumerable: false, configurable: true });
145
+ }
146
+ const keep = (name, value) => {
147
+ if (!Reflect.defineProperty(scope, name, { value, writable: true, enumerable: true, configurable: true }))
148
+ stuck.push(name);
149
+ };
150
+ keep("setTimeout", timer(nativeSetTimeout, "setTimeout"));
151
+ keep("setInterval", timer(nativeSetInterval, "setInterval"));
152
+ if (crypto)
153
+ keep("crypto", crypto);
154
+ /*
155
+ * MAKE IT STICK. Every prototype on the chain is frozen, every property
156
+ * left on the global is made non-configurable and read-only, and the
157
+ * global takes no new ones: what a guest finds is what stays.
158
+ */
159
+ for (const at of chain.slice(1))
160
+ Object.freeze(at);
161
+ for (const key of Reflect.ownKeys(scope)) {
162
+ const descriptor = Reflect.getOwnPropertyDescriptor(scope, key);
163
+ Reflect.defineProperty(scope, key, "value" in descriptor ? { ...descriptor, writable: false, configurable: false } : { ...descriptor, configurable: false });
164
+ }
165
+ /* Where an engine will not have a global made inextensible, a guest can add its own names: nothing it adds reaches anything removed. */
166
+ let sealed;
167
+ try {
168
+ sealed = Reflect.preventExtensions(scope);
169
+ }
170
+ catch {
171
+ sealed = false;
172
+ }
173
+ return { removed, stuck, sealed };
174
+ }
175
+ //# sourceMappingURL=harden.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harden.js","sourceRoot":"","sources":["../../src/worker/harden.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import "@remote-dom/core/polyfill";
2
+ import { type Guest } from "../channel.js";
3
+ import { type Hardening } from "./harden.js";
4
+ /** The element a worker guest draws into; the host's container stands for it. */
5
+ export declare const GUEST_ROOT = "graview-root";
6
+ /**
7
+ * WHAT HARDENING TOOK (FR-70), before any guest code ran. Should a name
8
+ * outside the allowlist refuse to go, the runtime stops here: no guest
9
+ * code runs in a worker that is not hardened, and the host hears it fail
10
+ * to start rather than a guest that is not held. Outside a worker (a test
11
+ * of the runtime in Node) there is no worker's global to harden, and
12
+ * `worker` says so.
13
+ */
14
+ export declare const hardening: Hardening;
15
+ /** A guest in a worker: a frame guest's channel, and the root its kit elements go in. */
16
+ export interface WorkerGuest extends Guest {
17
+ /** Append kit elements here (`document.createElement("gv-card")`, …); the host draws them. */
18
+ readonly root: Element;
19
+ }
20
+ /**
21
+ * Connect a worker guest to its host: say ready to the worker's owner,
22
+ * take its hello, and draw from then on through the port. One connection
23
+ * per worker; asking again returns it.
24
+ */
25
+ export declare function connectGuest(): WorkerGuest;
26
+ export { GUEST_GLOBALS, INERT, LANGUAGE, OBJECT_PROTOTYPE, PLATFORM, POLYFILLED_DOM } from "./harden.js";
27
+ export type { Hardening } from "./harden.js";
28
+ export { GUEST_KIT, KIT_LINK_TARGETS, KIT_TONES } from "../kit.js";
29
+ export type { GuestKitElement, Kit, KitComponent, KitEvent, KitProperty, KitPropertyType, KitTone } from "../kit.js";
30
+ export type { Guest } from "../channel.js";
31
+ export type { GuestAct, GuestAnswer, GuestEdge, GuestNode, GuestProps, GuestRefusal } from "../protocol.js";
32
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/worker/index.ts"],"names":[],"mappings":"AAqBA,OAAO,2BAA2B,CAAC;AAEnC,OAAO,EAAa,KAAK,KAAK,EAAE,MAAM,eAAe,CAAC;AAGtD,OAAO,EAAU,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAGrD,iFAAiF;AACjF,eAAO,MAAM,UAAU,iBAAiB,CAAC;AAKzC;;;;;;;GAOG;AACH,eAAO,MAAM,SAAS,EAAE,SAAmH,CAAC;AAG5I,yFAAyF;AACzF,MAAM,WAAW,WAAY,SAAQ,KAAK;IACxC,8FAA8F;IAC9F,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACxB;AAID;;;;GAIG;AACH,wBAAgB,YAAY,IAAI,WAAW,CA6C1C;AAED,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,QAAQ,EAAE,gBAAgB,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACzG,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACnE,YAAY,EAAE,eAAe,EAAE,GAAG,EAAE,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACrH,YAAY,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC3C,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,92 @@
1
+ /*
2
+ * A GUEST VIEW IN A WORKER (FR-68): `@graview/guest/worker`.
3
+ *
4
+ * Where a frame cannot be nested — a chat's widget, whose own sandbox will
5
+ * not frame another origin — a view somebody else wrote runs in a classic
6
+ * Web Worker the host starts from a `blob:` URL. This entry is the guest's
7
+ * whole runtime there, and it must be the first thing the worker runs:
8
+ *
9
+ * 1. it keeps, for itself, how to hear the host and say ready (natives.ts);
10
+ * 2. it boots Remote DOM's DOM polyfill, so the guest has a `document`;
11
+ * 3. it defines the component kit as remote elements (kit.ts, elements.ts);
12
+ * 4. it hardens the worker's global before guest code runs (harden.ts),
13
+ * and stops if it cannot;
14
+ * 5. it offers the guest the same API a frame guest has — props in,
15
+ * `act`, `navigate`, `size` — and a `root` to draw the kit into.
16
+ *
17
+ * The protocol is FR-04's (protocol.ts): ready, a hello with a nonce and a
18
+ * port, and everything after over the port. What the guest draws goes to
19
+ * the host as Remote DOM mutation records, and the host draws only the kit.
20
+ */
21
+ import { natives } from "./natives.js";
22
+ import "@remote-dom/core/polyfill";
23
+ import { RemoteRootElement } from "@remote-dom/core/elements";
24
+ import { openGuest } from "../channel.js";
25
+ import { GUEST_KIT } from "../kit.js";
26
+ import { defineKit } from "./elements.js";
27
+ import { harden } from "./harden.js";
28
+ import { createListenerLedger } from "./listeners.js";
29
+ /** The element a worker guest draws into; the host's container stands for it. */
30
+ export const GUEST_ROOT = "graview-root";
31
+ defineKit(GUEST_KIT);
32
+ customElements.define(GUEST_ROOT, RemoteRootElement);
33
+ /**
34
+ * WHAT HARDENING TOOK (FR-70), before any guest code ran. Should a name
35
+ * outside the allowlist refuse to go, the runtime stops here: no guest
36
+ * code runs in a worker that is not hardened, and the host hears it fail
37
+ * to start rather than a guest that is not held. Outside a worker (a test
38
+ * of the runtime in Node) there is no worker's global to harden, and
39
+ * `worker` says so.
40
+ */
41
+ export const hardening = "WorkerGlobalScope" in globalThis ? harden() : { removed: [], stuck: [], sealed: false, worker: false };
42
+ if (hardening.stuck.length > 0)
43
+ throw new Error(`The guest's worker could not be hardened: ${hardening.stuck.join(", ")} would not go.`);
44
+ let shared;
45
+ /**
46
+ * Connect a worker guest to its host: say ready to the worker's owner,
47
+ * take its hello, and draw from then on through the port. One connection
48
+ * per worker; asking again returns it.
49
+ */
50
+ export function connectGuest() {
51
+ if (shared)
52
+ return shared;
53
+ /*
54
+ * A listener cannot be cloned into a message, so it crosses as an id the
55
+ * host hands back when the viewer raises the event, and is let go when
56
+ * what it was on leaves the tree (listeners.ts).
57
+ */
58
+ const ledger = createListenerLedger();
59
+ const opened = openGuest({
60
+ listen(heard) {
61
+ natives.listen(heard);
62
+ return () => natives.unlisten(heard);
63
+ },
64
+ /* A dedicated worker hears only its owner: whoever posts to it is the host that started it. */
65
+ fromHost: () => true,
66
+ ready: (message) => natives.post(message),
67
+ }, { onEvent: (event) => void ledger.listener(event.listener)?.(event.detail) });
68
+ /* A microtask's mutations go as one message: building a card is one render, not one per node. */
69
+ let pending;
70
+ const connection = {
71
+ mutate(records) {
72
+ if (!pending) {
73
+ pending = [];
74
+ natives.microtask(() => {
75
+ const records = pending ?? [];
76
+ pending = undefined;
77
+ opened.send({ type: "render", records: ledger.encode(records) });
78
+ });
79
+ }
80
+ pending.push(...records);
81
+ },
82
+ /* The kit declares no methods, so there is nothing of the host's to call. */
83
+ call: () => undefined,
84
+ };
85
+ const root = document.createElement(GUEST_ROOT);
86
+ root.connect(connection);
87
+ shared = Object.defineProperty(opened.guest, "root", { value: root, enumerable: true });
88
+ return shared;
89
+ }
90
+ export { GUEST_GLOBALS, INERT, LANGUAGE, OBJECT_PROTOTYPE, PLATFORM, POLYFILLED_DOM } from "./harden.js";
91
+ export { GUEST_KIT, KIT_LINK_TARGETS, KIT_TONES } from "../kit.js";
92
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/worker/index.ts"],"names":[],"mappings":"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"}