@cloudcrane/app-runtime 0.1.0 → 0.2.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/README.md CHANGED
@@ -12,10 +12,26 @@ const { html, sha256, runtime } = compile(spec);
12
12
  ```
13
13
 
14
14
  - `compile(spec)` returns the page, its sha256 and the runtime it was built
15
- with (`@cloudcrane/app-runtime@0.1.0+<hash>`); it throws `CompileError`
15
+ with (`@cloudcrane/app-runtime@0.2.0+<hash>`); it throws `CompileError`
16
16
  listing every problem when the spec doesn't validate.
17
17
  - Each runtime version is locked to one bundle hash (`runtime-lock.json`), so a
18
18
  version always draws apps the same way.
19
+ - A coded component runs in a frame that's sandboxed (scripts only, so it has
20
+ no storage and nothing of the page's), in a closed shadow root, reached only
21
+ through a `MessagePort`. Under CloudCrane's lockdown the lockdown makes the
22
+ frame (`window.__ccFrame`); elsewhere the runtime makes the same kind. The
23
+ page drives it: a seed and the inputs, then its clock each frame, paused
24
+ while hidden. The game kit turns that clock into fixed steps, so a game moves
25
+ the same way for the same time and seed:
26
+
27
+ ```js
28
+ game.start({ rate: 6, setup() {}, step() {}, draw(g, width, height) {} });
29
+ game.on("swipe", (dir) => {}); // also "tap" and "input"
30
+ game.state = { score }; // shown at /ui/coded/<id>/state
31
+ game.emit("over", { score }); // the screen's action for "over" runs
32
+ game.random(); // seeded by the page
33
+ ```
34
+
19
35
  - `@cloudcrane/app-runtime/host`: what a host publishing spec apps needs in one
20
36
  import (validate, compile, derive the blueprint).
21
37
 
@@ -1,6 +1,6 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import { canonical, validateSpec } from "@cloudcrane/app-spec";
3
- import { DATESTRIP_CSS } from "../runtime/styles.js";
3
+ import { CODED_CSS, DATESTRIP_CSS } from "../runtime/styles.js";
4
4
  import { tokensCss } from "../runtime/theme.js";
5
5
  import { RUNTIME_JS, RUNTIME_SHA256, RUNTIME_VERSION } from "./runtime.generated.js";
6
6
  // The compiler: a spec in, one HTML page out, the same bytes every time for the
@@ -30,8 +30,10 @@ export function compile(input) {
30
30
  if (spec.manifest.runtime !== RUNTIME_VERSION)
31
31
  throw new CompileError([{ at: "manifest.runtime", problem: `this compiler builds runtime ${RUNTIME_VERSION}` }]);
32
32
  // Only what drawing the app needs goes in the page: not the journeys, promises or tests.
33
+ // Coded components go in only when there are some.
33
34
  const inPage = {
34
35
  module: spec.module,
36
+ ...(Object.keys(spec.components).length ? { components: spec.components } : {}),
35
37
  data: spec.data,
36
38
  logic: spec.logic,
37
39
  surface: spec.surface,
@@ -41,7 +43,7 @@ export function compile(input) {
41
43
  '<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">' +
42
44
  `<meta name="cc-runtime" content="${RUNTIME_VERSION}">` +
43
45
  `<title>${escapeHtml(spec.module.name)}</title>` +
44
- `<style>${tokensCss(spec.tokens)}${BASE_CSS}${DATESTRIP_CSS}</style>` +
46
+ `<style>${tokensCss(spec.tokens)}${BASE_CSS}${DATESTRIP_CSS}${CODED_CSS}</style>` +
45
47
  '</head><body><main id="app"></main>' +
46
48
  `<script type="application/json" id="cc-spec">${scriptSafe(canonical(inPage))}</script>` +
47
49
  `<script type="module">${RUNTIME_JS}</script>` +