@crowdedkingdoms/crowdyjs 17.13.0-dev.1 → 18.0.0-dev.1
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/MIGRATION.md +163 -1
- package/README.md +142 -146
- package/dist/crowdy-client.d.ts +12 -31
- package/dist/crowdy-client.d.ts.map +1 -1
- package/dist/crowdy-client.js +15 -37
- package/dist/crowdy-dsh/bridge.d.ts.map +1 -1
- package/dist/crowdy-dsh/bridge.js +3 -6
- package/dist/crowdy-studio/controller.d.ts +59 -57
- package/dist/crowdy-studio/controller.d.ts.map +1 -1
- package/dist/crowdy-studio/controller.js +268 -206
- package/dist/crowdy-studio/diagnostics.d.ts +3 -12
- package/dist/crowdy-studio/diagnostics.d.ts.map +1 -1
- package/dist/crowdy-studio/dom-shell.d.ts +2 -4
- package/dist/crowdy-studio/dom-shell.d.ts.map +1 -1
- package/dist/crowdy-studio/dom-shell.js +16 -47
- package/dist/crowdy-studio/embed/hud-layer.d.ts +1 -1
- package/dist/crowdy-studio/embed/panel.d.ts +3 -12
- package/dist/crowdy-studio/embed/panel.d.ts.map +1 -1
- package/dist/crowdy-studio/embed/panel.js +3 -6
- package/dist/crowdy-studio/index.d.ts +1 -3
- package/dist/crowdy-studio/index.d.ts.map +1 -1
- package/dist/crowdy-studio/index.js +0 -2
- package/dist/crowdy-studio/models.d.ts +3 -4
- package/dist/crowdy-studio/models.d.ts.map +1 -1
- package/dist/crowdy-studio/starter-projects.d.ts +8 -4
- package/dist/crowdy-studio/starter-projects.d.ts.map +1 -1
- package/dist/crowdy-studio/starter-projects.js +83 -100
- package/dist/domains/appAccess.d.ts +14 -1
- package/dist/domains/appAccess.d.ts.map +1 -1
- package/dist/domains/appAccess.js +37 -1
- package/dist/domains/exec.d.ts +162 -15
- package/dist/domains/exec.d.ts.map +1 -1
- package/dist/domains/exec.js +180 -18
- package/dist/domains/host.d.ts +3 -3
- package/dist/domains/host.js +3 -3
- package/dist/domains/marketplace.d.ts +9 -58
- package/dist/domains/marketplace.d.ts.map +1 -1
- package/dist/domains/marketplace.js +9 -106
- package/dist/domains/playerWallet.d.ts +6 -12
- package/dist/domains/playerWallet.d.ts.map +1 -1
- package/dist/domains/playerWallet.js +6 -21
- package/dist/errors.d.ts +7 -13
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +6 -10
- package/dist/generated/graphql.d.ts +1384 -7977
- package/dist/generated/graphql.d.ts.map +1 -1
- package/dist/generated/graphql.js +22 -321
- package/dist/grid-mods/exec-client-halves.d.ts +156 -0
- package/dist/grid-mods/exec-client-halves.d.ts.map +1 -0
- package/dist/grid-mods/exec-client-halves.js +356 -0
- package/dist/grid-mods/grid-host-calls.d.ts +29 -15
- package/dist/grid-mods/grid-host-calls.d.ts.map +1 -1
- package/dist/grid-mods/grid-host-calls.js +40 -44
- package/dist/grid-mods/index.d.ts +1 -0
- package/dist/grid-mods/index.d.ts.map +1 -1
- package/dist/grid-mods/index.js +1 -0
- package/dist/grid-mods/mod-runtime.d.ts +21 -6
- package/dist/grid-mods/mod-runtime.d.ts.map +1 -1
- package/dist/grid-mods/mod-runtime.js +6 -2
- package/dist/grid-scope.d.ts +0 -188
- package/dist/grid-scope.d.ts.map +1 -1
- package/dist/grid-scope.js +0 -69
- package/dist/index.d.ts +12 -18
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -16
- package/dist/kit/actions.d.ts +5 -9
- package/dist/kit/actions.d.ts.map +1 -1
- package/dist/kit/actions.js +5 -9
- package/dist/kit/index.d.ts +2 -33
- package/dist/kit/index.d.ts.map +1 -1
- package/dist/kit/index.js +1 -32
- package/dist/kit/kit.d.ts +8 -208
- package/dist/kit/kit.d.ts.map +1 -1
- package/dist/kit/kit.js +5 -163
- package/dist/kit/social.d.ts +1 -3
- package/dist/kit/social.d.ts.map +1 -1
- package/dist/kit/social.js +1 -3
- package/dist/kit/wire.d.ts +16 -5
- package/dist/kit/wire.d.ts.map +1 -1
- package/dist/kit/wire.js +19 -5
- package/dist/live-coding/assets/browser-authoring-index.json +1 -1
- package/dist/live-coding/assets/manifest.json +1 -1
- package/dist/live-coding/browser-authoring-index.generated.d.ts.map +1 -1
- package/dist/live-coding/browser-authoring-index.generated.js +1496 -4386
- package/dist/live-coding/rust-analysis.d.ts.map +1 -1
- package/dist/live-coding/rust-analysis.js +31 -23
- package/dist/player-runtime/client-host-calls.d.ts +8 -0
- package/dist/player-runtime/client-host-calls.d.ts.map +1 -0
- package/dist/player-runtime/client-host-calls.js +28 -0
- package/dist/player-runtime/glue-runtime.d.ts +27 -10
- package/dist/player-runtime/glue-runtime.d.ts.map +1 -1
- package/dist/player-runtime/glue-runtime.js +40 -45
- package/dist/player-runtime/glue-sab.d.ts +2 -2
- package/dist/player-runtime/glue-sab.js +2 -2
- package/dist/player-runtime/player-code-broker.d.ts +80 -24
- package/dist/player-runtime/player-code-broker.d.ts.map +1 -1
- package/dist/player-runtime/player-code-broker.js +169 -41
- package/dist/player-runtime/player-glue-worker.d.ts +8 -8
- package/dist/player-runtime/player-glue-worker.d.ts.map +1 -1
- package/dist/player-runtime/player-glue-worker.js +26 -9
- package/dist/stores/actors.d.ts +12 -2
- package/dist/stores/actors.d.ts.map +1 -1
- package/dist/stores/actors.js +43 -18
- package/dist/stores/chunks.d.ts +12 -0
- package/dist/stores/chunks.d.ts.map +1 -1
- package/dist/stores/chunks.js +112 -39
- package/dist/stores/durable.d.ts.map +1 -1
- package/dist/stores/durable.js +2 -1
- package/dist/stores/inbox.d.ts +1 -1
- package/dist/stores/inbox.d.ts.map +1 -1
- package/dist/stores/index.d.ts +0 -11
- package/dist/stores/index.d.ts.map +1 -1
- package/dist/stores/index.js +0 -4
- package/dist/stores/session.d.ts +0 -2
- package/dist/stores/session.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/crowdy-studio/model-lint-log.d.ts +0 -76
- package/dist/crowdy-studio/model-lint-log.d.ts.map +0 -1
- package/dist/crowdy-studio/model-lint-log.js +0 -93
- package/dist/crowdy-studio/model-lint.d.ts +0 -61
- package/dist/crowdy-studio/model-lint.d.ts.map +0 -1
- package/dist/crowdy-studio/model-lint.js +0 -45
- package/dist/domains/compute.d.ts +0 -208
- package/dist/domains/compute.d.ts.map +0 -1
- package/dist/domains/compute.js +0 -274
- package/dist/domains/controlPlane.d.ts +0 -38
- package/dist/domains/controlPlane.d.ts.map +0 -1
- package/dist/domains/controlPlane.js +0 -43
- package/dist/domains/gameModel.d.ts +0 -1174
- package/dist/domains/gameModel.d.ts.map +0 -1
- package/dist/domains/gameModel.js +0 -1333
- package/dist/domains/playerCompute.d.ts +0 -91
- package/dist/domains/playerCompute.d.ts.map +0 -1
- package/dist/domains/playerCompute.js +0 -136
- package/dist/domains/playerModel.d.ts +0 -20
- package/dist/domains/playerModel.d.ts.map +0 -1
- package/dist/domains/playerModel.js +0 -54
- package/dist/kit/abilities.d.ts +0 -66
- package/dist/kit/abilities.d.ts.map +0 -1
- package/dist/kit/abilities.js +0 -71
- package/dist/kit/blueprints/combat.d.ts +0 -81
- package/dist/kit/blueprints/combat.d.ts.map +0 -1
- package/dist/kit/blueprints/combat.js +0 -357
- package/dist/kit/blueprints/core.d.ts +0 -222
- package/dist/kit/blueprints/core.d.ts.map +0 -1
- package/dist/kit/blueprints/core.js +0 -185
- package/dist/kit/blueprints/decks.d.ts +0 -50
- package/dist/kit/blueprints/decks.d.ts.map +0 -1
- package/dist/kit/blueprints/decks.js +0 -163
- package/dist/kit/blueprints/economy.d.ts +0 -88
- package/dist/kit/blueprints/economy.d.ts.map +0 -1
- package/dist/kit/blueprints/economy.js +0 -533
- package/dist/kit/blueprints/guild.d.ts +0 -51
- package/dist/kit/blueprints/guild.d.ts.map +0 -1
- package/dist/kit/blueprints/guild.js +0 -50
- package/dist/kit/blueprints/index.d.ts +0 -23
- package/dist/kit/blueprints/index.d.ts.map +0 -1
- package/dist/kit/blueprints/index.js +0 -22
- package/dist/kit/blueprints/inventory.d.ts +0 -84
- package/dist/kit/blueprints/inventory.d.ts.map +0 -1
- package/dist/kit/blueprints/inventory.js +0 -257
- package/dist/kit/blueprints/leaderboards.d.ts +0 -49
- package/dist/kit/blueprints/leaderboards.d.ts.map +0 -1
- package/dist/kit/blueprints/leaderboards.js +0 -126
- package/dist/kit/blueprints/liveops.d.ts +0 -42
- package/dist/kit/blueprints/liveops.d.ts.map +0 -1
- package/dist/kit/blueprints/liveops.js +0 -170
- package/dist/kit/blueprints/locks.d.ts +0 -82
- package/dist/kit/blueprints/locks.d.ts.map +0 -1
- package/dist/kit/blueprints/locks.js +0 -155
- package/dist/kit/blueprints/loot.d.ts +0 -90
- package/dist/kit/blueprints/loot.d.ts.map +0 -1
- package/dist/kit/blueprints/loot.js +0 -229
- package/dist/kit/blueprints/matches.d.ts +0 -84
- package/dist/kit/blueprints/matches.d.ts.map +0 -1
- package/dist/kit/blueprints/matches.js +0 -349
- package/dist/kit/blueprints/moderation.d.ts +0 -32
- package/dist/kit/blueprints/moderation.d.ts.map +0 -1
- package/dist/kit/blueprints/moderation.js +0 -140
- package/dist/kit/blueprints/npcs.d.ts +0 -78
- package/dist/kit/blueprints/npcs.d.ts.map +0 -1
- package/dist/kit/blueprints/npcs.js +0 -125
- package/dist/kit/blueprints/plots.d.ts +0 -63
- package/dist/kit/blueprints/plots.d.ts.map +0 -1
- package/dist/kit/blueprints/plots.js +0 -151
- package/dist/kit/blueprints/progression.d.ts +0 -68
- package/dist/kit/blueprints/progression.d.ts.map +0 -1
- package/dist/kit/blueprints/progression.js +0 -324
- package/dist/kit/blueprints/quests.d.ts +0 -72
- package/dist/kit/blueprints/quests.d.ts.map +0 -1
- package/dist/kit/blueprints/quests.js +0 -285
- package/dist/kit/blueprints/worldsim.d.ts +0 -91
- package/dist/kit/blueprints/worldsim.d.ts.map +0 -1
- package/dist/kit/blueprints/worldsim.js +0 -468
- package/dist/kit/combat.d.ts +0 -141
- package/dist/kit/combat.d.ts.map +0 -1
- package/dist/kit/combat.js +0 -196
- package/dist/kit/decks.d.ts +0 -157
- package/dist/kit/decks.d.ts.map +0 -1
- package/dist/kit/decks.js +0 -186
- package/dist/kit/director.d.ts +0 -88
- package/dist/kit/director.d.ts.map +0 -1
- package/dist/kit/director.js +0 -86
- package/dist/kit/economy.d.ts +0 -289
- package/dist/kit/economy.d.ts.map +0 -1
- package/dist/kit/economy.js +0 -427
- package/dist/kit/engine.d.ts +0 -48
- package/dist/kit/engine.d.ts.map +0 -1
- package/dist/kit/engine.js +0 -113
- package/dist/kit/features.d.ts +0 -60
- package/dist/kit/features.d.ts.map +0 -1
- package/dist/kit/features.js +0 -65
- package/dist/kit/instances.d.ts +0 -52
- package/dist/kit/instances.d.ts.map +0 -1
- package/dist/kit/instances.js +0 -60
- package/dist/kit/inventory.d.ts +0 -129
- package/dist/kit/inventory.d.ts.map +0 -1
- package/dist/kit/inventory.js +0 -200
- package/dist/kit/leaderboards.d.ts +0 -86
- package/dist/kit/leaderboards.d.ts.map +0 -1
- package/dist/kit/leaderboards.js +0 -133
- package/dist/kit/liveops.d.ts +0 -112
- package/dist/kit/liveops.d.ts.map +0 -1
- package/dist/kit/liveops.js +0 -183
- package/dist/kit/loot.d.ts +0 -128
- package/dist/kit/loot.d.ts.map +0 -1
- package/dist/kit/loot.js +0 -160
- package/dist/kit/matches.d.ts +0 -301
- package/dist/kit/matches.d.ts.map +0 -1
- package/dist/kit/matches.js +0 -458
- package/dist/kit/matchmaking.d.ts +0 -57
- package/dist/kit/matchmaking.d.ts.map +0 -1
- package/dist/kit/matchmaking.js +0 -59
- package/dist/kit/minigames.d.ts +0 -30
- package/dist/kit/minigames.d.ts.map +0 -1
- package/dist/kit/minigames.js +0 -38
- package/dist/kit/mobs.d.ts +0 -90
- package/dist/kit/mobs.d.ts.map +0 -1
- package/dist/kit/mobs.js +0 -98
- package/dist/kit/moderation.d.ts +0 -73
- package/dist/kit/moderation.d.ts.map +0 -1
- package/dist/kit/moderation.js +0 -103
- package/dist/kit/movement.d.ts +0 -78
- package/dist/kit/movement.d.ts.map +0 -1
- package/dist/kit/movement.js +0 -103
- package/dist/kit/notifications.d.ts +0 -45
- package/dist/kit/notifications.d.ts.map +0 -1
- package/dist/kit/notifications.js +0 -67
- package/dist/kit/npcs.d.ts +0 -226
- package/dist/kit/npcs.d.ts.map +0 -1
- package/dist/kit/npcs.js +0 -141
- package/dist/kit/objects.d.ts +0 -116
- package/dist/kit/objects.d.ts.map +0 -1
- package/dist/kit/objects.js +0 -119
- package/dist/kit/pets.d.ts +0 -85
- package/dist/kit/pets.d.ts.map +0 -1
- package/dist/kit/pets.js +0 -96
- package/dist/kit/plots.d.ts +0 -85
- package/dist/kit/plots.d.ts.map +0 -1
- package/dist/kit/plots.js +0 -113
- package/dist/kit/progression.d.ts +0 -181
- package/dist/kit/progression.d.ts.map +0 -1
- package/dist/kit/progression.js +0 -265
- package/dist/kit/quests.d.ts +0 -171
- package/dist/kit/quests.d.ts.map +0 -1
- package/dist/kit/quests.js +0 -237
- package/dist/kit/racing.d.ts +0 -85
- package/dist/kit/racing.d.ts.map +0 -1
- package/dist/kit/racing.js +0 -99
- package/dist/kit/shared.d.ts +0 -73
- package/dist/kit/shared.d.ts.map +0 -1
- package/dist/kit/shared.js +0 -101
- package/dist/kit/telemetry.d.ts +0 -66
- package/dist/kit/telemetry.d.ts.map +0 -1
- package/dist/kit/telemetry.js +0 -133
- package/dist/kit/territory.d.ts +0 -97
- package/dist/kit/territory.d.ts.map +0 -1
- package/dist/kit/territory.js +0 -114
- package/dist/kit/worldsim.d.ts +0 -263
- package/dist/kit/worldsim.d.ts.map +0 -1
- package/dist/kit/worldsim.js +0 -268
- package/dist/stores/model.d.ts +0 -81
- package/dist/stores/model.d.ts.map +0 -1
- package/dist/stores/model.js +0 -163
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rust-analysis.d.ts","sourceRoot":"","sources":["../../src/live-coding/rust-analysis.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,cAAc,EACd,UAAU,EACV,cAAc,EACd,KAAK,EACL,QAAQ,EACR,QAAQ,EAET,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAEV,aAAa,EAGd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"rust-analysis.d.ts","sourceRoot":"","sources":["../../src/live-coding/rust-analysis.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,cAAc,EACd,UAAU,EACV,cAAc,EACd,KAAK,EACL,QAAQ,EACR,QAAQ,EAET,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAEV,aAAa,EAGd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAqHhD,qBAAa,YAAY;IAIrB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAJhC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAuC;IAE7D,OAAO;WAKM,MAAM,CAAC,OAAO,EAAE;QAC3B,aAAa,EAAE,MAAM,CAAC;QACtB,cAAc,EAAE,MAAM,CAAC;QACvB,aAAa,EAAE,aAAa,CAAC;KAC9B,GAAG,OAAO,CAAC,YAAY,CAAC;IAWzB,WAAW,CAAC,QAAQ,EAAE,eAAe,GAAG,UAAU,EAAE;IAIpD,WAAW,CACT,QAAQ,EAAE,eAAe,EACzB,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,SAAS,eAAe,EAAE,GACpC,cAAc,EAAE;IAoCnB,KAAK,CACH,QAAQ,EAAE,eAAe,EACzB,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,SAAS,eAAe,EAAE,GACpC,KAAK,GAAG,IAAI;IAwCf,eAAe,CAAC,QAAQ,EAAE,eAAe,GAAG,cAAc,EAAE;IAU5D,UAAU,CACR,QAAQ,EAAE,eAAe,EACzB,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,SAAS,eAAe,EAAE,GACpC,QAAQ,GAAG,IAAI;IAWlB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAI7B,OAAO,IAAI,IAAI;IAKf,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,OAAO;CA6ChB"}
|
|
@@ -54,19 +54,19 @@ const RUST_KEYWORDS = [
|
|
|
54
54
|
const TARGET_SNIPPETS = {
|
|
55
55
|
server: [
|
|
56
56
|
{
|
|
57
|
-
label: '
|
|
57
|
+
label: 'mod hub',
|
|
58
58
|
kind: 15,
|
|
59
|
-
detail: 'SERVER
|
|
60
|
-
documentation: 'Runs
|
|
61
|
-
insertText: '
|
|
59
|
+
detail: 'SERVER: a ck-exec mod (spawn, load, persist, handle)',
|
|
60
|
+
documentation: 'Runs on the platform as a hub keyed by the grid, in its owner\u2019s sandbox; its node API calls reach only this grid. Crowdy Studio Invoke calls one of its endpoints (`state` by default).',
|
|
61
|
+
insertText: 'use ckx_sdk::prelude::*;\n\n#[derive(Serialize, Deserialize, Default)]\npub struct Mod {\n $1\n}\n\nimpl Hub for Mod {\n fn spawn(_ctx: &Ctx, _seed: &[u8]) -> Result<Self> {\n Ok(Self::default())\n }\n\n fn load(_ctx: &Ctx, snapshot: &[u8], _from_version: u64) -> Result<Self> {\n decode(snapshot)\n }\n\n fn persist(&mut self, _ctx: &Ctx) -> Result<Vec<u8>> {\n encode(self)\n }\n\n fn handle(&mut self, _ctx: &Ctx, call: Call<\'_>) -> Result<Vec<u8>> {\n match call.method {\n "state" => encode(&*self),\n m => Err(Error(format!("no endpoint `{m}`"))),\n }\n }\n}\n\nckx_sdk::export_hub!(Mod);',
|
|
62
62
|
sortText: '0-server-lifecycle',
|
|
63
63
|
},
|
|
64
64
|
{
|
|
65
|
-
label: '
|
|
65
|
+
label: 'mod endpoint',
|
|
66
66
|
kind: 15,
|
|
67
|
-
detail: 'SERVER
|
|
68
|
-
documentation: 'The
|
|
69
|
-
insertText: '
|
|
67
|
+
detail: 'SERVER: an endpoint in handle, called over an exec connection',
|
|
68
|
+
documentation: 'The platform names the caller (`call.player()`); author identity is never authority.',
|
|
69
|
+
insertText: '"${1:visit}" => {\n $2\n encode(&*self)\n}',
|
|
70
70
|
sortText: '0-server-invoke',
|
|
71
71
|
},
|
|
72
72
|
],
|
|
@@ -74,17 +74,17 @@ const TARGET_SNIPPETS = {
|
|
|
74
74
|
{
|
|
75
75
|
label: 'client lifecycle',
|
|
76
76
|
kind: 15,
|
|
77
|
-
detail: 'CLIENT init, tick, and
|
|
78
|
-
documentation: 'Runs in the browser
|
|
79
|
-
insertText: 'fn
|
|
77
|
+
detail: 'CLIENT half: init, tick, invoke and event entry points',
|
|
78
|
+
documentation: 'Runs in the visitor\u2019s browser sandbox. Page capabilities are exposed only through the broker allow-list, narrowed to what the visitor consented to. It ticks every tick_interval_ms (Cargo.toml).',
|
|
79
|
+
insertText: 'fn init() {\n $1\n}\n\nfn tick(_dt_ms: u32) {\n $2\n}\n\nfn invoke(payload: &[u8]) -> Vec<u8> {\n ${3:payload.to_vec()}\n}\n\nfn event(_payload: &[u8]) {}\n\ncrowdy_client_sdk::register_module!(init: init, tick: tick, invoke: invoke, event: event);',
|
|
80
80
|
sortText: '0-client-lifecycle',
|
|
81
81
|
},
|
|
82
82
|
{
|
|
83
83
|
label: 'client presentation tick',
|
|
84
84
|
kind: 15,
|
|
85
85
|
detail: 'CLIENT tick for allow-listed HUD/presentation effects',
|
|
86
|
-
documentation: 'Presentation calls cross PlayerCodeBroker; the language worker and guest module never receive page credentials.
|
|
87
|
-
insertText: 'fn
|
|
86
|
+
documentation: 'Presentation calls cross PlayerCodeBroker to the HUD the game offers; the language worker and guest module never receive page credentials.',
|
|
87
|
+
insertText: 'fn tick(_dt_ms: u32) {\n let _ = crowdy_client_sdk::api::hud_set(serde_json::json!({ "text": "${1:hello}" }));\n}',
|
|
88
88
|
sortText: '0-client-presentation',
|
|
89
89
|
},
|
|
90
90
|
],
|
|
@@ -132,7 +132,7 @@ export class RustAnalysis {
|
|
|
132
132
|
}
|
|
133
133
|
const target = targetForDocument(document);
|
|
134
134
|
if (target) {
|
|
135
|
-
for (const snippet of
|
|
135
|
+
for (const snippet of targetSnippets(target))
|
|
136
136
|
add(snippet);
|
|
137
137
|
}
|
|
138
138
|
for (const symbol of this.platformIndex.symbols) {
|
|
@@ -255,23 +255,31 @@ export class RustAnalysis {
|
|
|
255
255
|
}
|
|
256
256
|
}
|
|
257
257
|
}
|
|
258
|
+
function targetSnippets(target) {
|
|
259
|
+
return TARGET_SNIPPETS[target];
|
|
260
|
+
}
|
|
258
261
|
function targetForDocument(document) {
|
|
259
262
|
const first = document.path.split('/', 1)[0]?.toLowerCase();
|
|
260
263
|
return first === 'server' || first === 'client' ? first : null;
|
|
261
264
|
}
|
|
265
|
+
const SERVER_LIFECYCLE = ['spawn', 'load', 'persist', 'handle', 'on_world', 'on_timer'];
|
|
266
|
+
const CLIENT_LIFECYCLE = ['init', 'tick', 'invoke', 'event'];
|
|
262
267
|
function targetLifecycleNote(document, word) {
|
|
263
268
|
const target = targetForDocument(document);
|
|
264
|
-
if (
|
|
265
|
-
return
|
|
269
|
+
if (target === 'server' && SERVER_LIFECYCLE.includes(word)) {
|
|
270
|
+
return word === 'handle'
|
|
271
|
+
? 'SERVER lifecycle: a mod endpoint runs for the caller the platform names (`call.player()`); its node API calls reach only this grid.'
|
|
272
|
+
: 'SERVER lifecycle: the mod runs on the platform as a hub keyed by the grid, in its owner\u2019s sandbox, once its build succeeds.';
|
|
266
273
|
}
|
|
267
|
-
if (target === '
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
274
|
+
if (target === 'client' && CLIENT_LIFECYCLE.includes(word)) {
|
|
275
|
+
if (word === 'tick') {
|
|
276
|
+
return 'CLIENT ticks run in the visitor\u2019s browser sandbox every tick_interval_ms (Cargo.toml); all page effects cross the PlayerCodeBroker allow-list, narrowed to what the visitor consented to.';
|
|
277
|
+
}
|
|
278
|
+
return word === 'invoke'
|
|
279
|
+
? 'CLIENT invoke answers the page (PlayerCodeBroker.invoke); its reply goes back to the game as bytes.'
|
|
280
|
+
: 'CLIENT code is loaded from the exact hash-bound artifact the grid serves for this CLIENT half.';
|
|
271
281
|
}
|
|
272
|
-
return
|
|
273
|
-
? 'CLIENT ticks execute inside the browser guest sandbox only when PlayerCodeBroker.tickIntervalMs is set; all page effects cross the PlayerCodeBroker allow-list.'
|
|
274
|
-
: 'CLIENT lifecycle code is loaded from the exact hash-bound artifact produced for this project version.';
|
|
282
|
+
return null;
|
|
275
283
|
}
|
|
276
284
|
function visit(node, callback) {
|
|
277
285
|
callback(node);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The host calls a ck-exec mod's CLIENT half may make, grouped by capability (04 §4): the
|
|
3
|
+
* client half of the platform host catalog less what only the legacy engines answered (the
|
|
4
|
+
* `model` group, `sessions_list` and `grid_state_*`). It is exactly what crowdy-client-sdk
|
|
5
|
+
* wraps, and the broker's deny-by-default allowlist.
|
|
6
|
+
*/
|
|
7
|
+
export declare const EXEC_CLIENT_HOST_CALLS: Readonly<Record<string, ReadonlySet<string>>>;
|
|
8
|
+
//# sourceMappingURL=client-host-calls.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-host-calls.d.ts","sourceRoot":"","sources":["../../src/player-runtime/client-host-calls.ts"],"names":[],"mappings":"AAaA;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAS7E,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { GENERATED_HOST_CATALOG } from './host-catalog.generated.js';
|
|
2
|
+
/**
|
|
3
|
+
* Client calls in the platform catalog that only the legacy engines answered, besides the
|
|
4
|
+
* Game Model group: crowdy-client-sdk does not wrap them, and nothing in the browser answers
|
|
5
|
+
* them.
|
|
6
|
+
*/
|
|
7
|
+
const LEGACY_HOST_CALLS = new Set([
|
|
8
|
+
'sessions_list',
|
|
9
|
+
'grid_state_get',
|
|
10
|
+
'grid_state_set',
|
|
11
|
+
]);
|
|
12
|
+
/**
|
|
13
|
+
* The host calls a ck-exec mod's CLIENT half may make, grouped by capability (04 §4): the
|
|
14
|
+
* client half of the platform host catalog less what only the legacy engines answered (the
|
|
15
|
+
* `model` group, `sessions_list` and `grid_state_*`). It is exactly what crowdy-client-sdk
|
|
16
|
+
* wraps, and the broker's deny-by-default allowlist.
|
|
17
|
+
*/
|
|
18
|
+
export const EXEC_CLIENT_HOST_CALLS = (() => {
|
|
19
|
+
var _a;
|
|
20
|
+
const groups = {};
|
|
21
|
+
for (const fn of GENERATED_HOST_CATALOG.functions) {
|
|
22
|
+
if (!fn.targets.includes('client') || fn.group === 'model' || LEGACY_HOST_CALLS.has(fn.name)) {
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
(groups[_a = fn.group] ?? (groups[_a] = new Set())).add(fn.name);
|
|
26
|
+
}
|
|
27
|
+
return groups;
|
|
28
|
+
})();
|
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Factored, environment-agnostic core of the platform glue
|
|
3
|
-
*
|
|
2
|
+
* Factored, environment-agnostic core of the platform glue for a ck-exec mod's
|
|
3
|
+
* CLIENT half. This is the ONLY platform code that shares an execution context
|
|
4
4
|
* with an untrusted player module, so it is deliberately tiny and auditable
|
|
5
5
|
* and has NO dependency on worker globals, the DOM, or the SDK client — the
|
|
6
6
|
* browser worker entry ([player-glue-worker.ts]) and the Node integration
|
|
7
7
|
* test both drive this same core.
|
|
8
8
|
*
|
|
9
|
-
* ABI (
|
|
10
|
-
* with `log`, `now_ms`, `state_get`, `state_set`, and the JSON gateway
|
|
9
|
+
* ABI (crowdy-client-sdk `lib.rs`, CLIENT ABI 0): the guest imports module
|
|
10
|
+
* `ck` with `log`, `now_ms`, `state_get`, `state_set`, and the JSON gateway
|
|
11
11
|
* `host_call(ptr,len) -> u64` (packed `resp_ptr<<32 | resp_len`, guest frees
|
|
12
|
-
* with `ck_free`), plus `wasi_snapshot_preview1.random_get
|
|
13
|
-
* exports `memory`, `ck_alloc`, `ck_free`,
|
|
14
|
-
*
|
|
12
|
+
* with `ck_free`), plus `wasi_snapshot_preview1.random_get`, and nothing else.
|
|
13
|
+
* The guest exports `memory`, `ck_alloc`, `ck_free`, the `ck_fuel` meter the
|
|
14
|
+
* build's instrument step injects, and the module hooks `init`,
|
|
15
|
+
* `tick(dt_ms)`, `handle_invoke(ptr,len)->u64` and optional
|
|
16
|
+
* `on_event(ptr,len)`.
|
|
15
17
|
*
|
|
16
18
|
* `host_call` is SYNCHRONOUS from the guest's view. The single synchronous
|
|
17
19
|
* dependency this core takes is `hostCallSync(reqBytes) -> respBytes`; the
|
|
@@ -19,13 +21,19 @@
|
|
|
19
21
|
* (the worker blocks; the page/broker services the async SDK call and writes
|
|
20
22
|
* the reply back). Everything else here is pure.
|
|
21
23
|
*/
|
|
22
|
-
/** The host-call names
|
|
24
|
+
/** The host-call names a guest may send: the broker's allowlist, {@link EXEC_CLIENT_HOST_CALLS}. */
|
|
23
25
|
export declare const GLUE_HOST_FUNCTIONS: readonly string[];
|
|
26
|
+
/** The most of one `ck.log` message read out of guest memory, in bytes. */
|
|
27
|
+
export declare const GLUE_LOG_MAX_BYTES = 4096;
|
|
28
|
+
/** Every import a ck-exec CLIENT half may have (CLIENT ABI 0), by module. */
|
|
29
|
+
export declare const EXEC_CLIENT_ABI_IMPORTS: Readonly<Record<string, readonly string[]>>;
|
|
24
30
|
export interface GlueInitMessage {
|
|
25
31
|
type: 'init';
|
|
26
32
|
artifact: ArrayBuffer;
|
|
27
33
|
authority: 'player';
|
|
28
|
-
/**
|
|
34
|
+
/** A mod's CLIENT half, offered exactly {@link EXEC_CLIENT_ABI_IMPORTS}: the only engine. */
|
|
35
|
+
engine?: 'ck-exec';
|
|
36
|
+
/** Server-authored budget loaded into the module's mutable `ck_fuel` global; required. */
|
|
29
37
|
fuelPerDispatch?: string;
|
|
30
38
|
/** Legacy metadata; the hard watchdog is owned by the page-side broker. */
|
|
31
39
|
watchdogMs?: number;
|
|
@@ -68,12 +76,21 @@ export interface GuestExports {
|
|
|
68
76
|
export interface GlueRuntimeOptions {
|
|
69
77
|
/** Synchronous host-API gateway: JSON request bytes in, SDK Response-envelope bytes out. */
|
|
70
78
|
hostCallSync: (reqBytes: Uint8Array) => Uint8Array;
|
|
71
|
-
/**
|
|
79
|
+
/**
|
|
80
|
+
* Sink for guest `ck.log` (optional): crowdy-client-sdk's level (0 debug, 1 info, 2 warn,
|
|
81
|
+
* 3 error) and at most {@link GLUE_LOG_MAX_BYTES} of the message.
|
|
82
|
+
*/
|
|
72
83
|
onLog?: (level: number, message: string) => void;
|
|
73
84
|
/** Deterministic-enough randomness for the guest `random_get` (defaults to crypto). */
|
|
74
85
|
randomFill?: (buf: Uint8Array) => void;
|
|
75
86
|
now?: () => number;
|
|
87
|
+
/** The per-dispatch budget; a module is refused without one. */
|
|
76
88
|
fuelPerDispatch?: bigint | null;
|
|
89
|
+
/**
|
|
90
|
+
* `'ck-exec'`, the only engine: offer exactly {@link EXEC_CLIENT_ABI_IMPORTS} and refuse a
|
|
91
|
+
* module that does not export the `ck_fuel` meter, or a missing budget.
|
|
92
|
+
*/
|
|
93
|
+
engine?: 'ck-exec';
|
|
77
94
|
}
|
|
78
95
|
/**
|
|
79
96
|
* Drives one untrusted guest module: builds the `ck` + wasi import table,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"glue-runtime.d.ts","sourceRoot":"","sources":["../../src/player-runtime/glue-runtime.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"glue-runtime.d.ts","sourceRoot":"","sources":["../../src/player-runtime/glue-runtime.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Factored, environment-agnostic core of the platform glue
|
|
3
|
-
*
|
|
2
|
+
* Factored, environment-agnostic core of the platform glue for a ck-exec mod's
|
|
3
|
+
* CLIENT half. This is the ONLY platform code that shares an execution context
|
|
4
4
|
* with an untrusted player module, so it is deliberately tiny and auditable
|
|
5
5
|
* and has NO dependency on worker globals, the DOM, or the SDK client — the
|
|
6
6
|
* browser worker entry ([player-glue-worker.ts]) and the Node integration
|
|
7
7
|
* test both drive this same core.
|
|
8
8
|
*
|
|
9
|
-
* ABI (
|
|
10
|
-
* with `log`, `now_ms`, `state_get`, `state_set`, and the JSON gateway
|
|
9
|
+
* ABI (crowdy-client-sdk `lib.rs`, CLIENT ABI 0): the guest imports module
|
|
10
|
+
* `ck` with `log`, `now_ms`, `state_get`, `state_set`, and the JSON gateway
|
|
11
11
|
* `host_call(ptr,len) -> u64` (packed `resp_ptr<<32 | resp_len`, guest frees
|
|
12
|
-
* with `ck_free`), plus `wasi_snapshot_preview1.random_get
|
|
13
|
-
* exports `memory`, `ck_alloc`, `ck_free`,
|
|
14
|
-
*
|
|
12
|
+
* with `ck_free`), plus `wasi_snapshot_preview1.random_get`, and nothing else.
|
|
13
|
+
* The guest exports `memory`, `ck_alloc`, `ck_free`, the `ck_fuel` meter the
|
|
14
|
+
* build's instrument step injects, and the module hooks `init`,
|
|
15
|
+
* `tick(dt_ms)`, `handle_invoke(ptr,len)->u64` and optional
|
|
16
|
+
* `on_event(ptr,len)`.
|
|
15
17
|
*
|
|
16
18
|
* `host_call` is SYNCHRONOUS from the guest's view. The single synchronous
|
|
17
19
|
* dependency this core takes is `hostCallSync(reqBytes) -> respBytes`; the
|
|
@@ -19,11 +21,16 @@
|
|
|
19
21
|
* (the worker blocks; the page/broker services the async SDK call and writes
|
|
20
22
|
* the reply back). Everything else here is pure.
|
|
21
23
|
*/
|
|
22
|
-
import {
|
|
23
|
-
/** The host-call names
|
|
24
|
-
export const GLUE_HOST_FUNCTIONS =
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
import { EXEC_CLIENT_HOST_CALLS } from './client-host-calls.js';
|
|
25
|
+
/** The host-call names a guest may send: the broker's allowlist, {@link EXEC_CLIENT_HOST_CALLS}. */
|
|
26
|
+
export const GLUE_HOST_FUNCTIONS = Object.values(EXEC_CLIENT_HOST_CALLS).flatMap((fns) => [...fns]);
|
|
27
|
+
/** The most of one `ck.log` message read out of guest memory, in bytes. */
|
|
28
|
+
export const GLUE_LOG_MAX_BYTES = 4096;
|
|
29
|
+
/** Every import a ck-exec CLIENT half may have (CLIENT ABI 0), by module. */
|
|
30
|
+
export const EXEC_CLIENT_ABI_IMPORTS = {
|
|
31
|
+
ck: ['log', 'now_ms', 'state_get', 'state_set', 'host_call'],
|
|
32
|
+
wasi_snapshot_preview1: ['random_get'],
|
|
33
|
+
};
|
|
27
34
|
/**
|
|
28
35
|
* Parse the server-authored budget used to refill an instrumented artifact's
|
|
29
36
|
* mutable `ck_fuel` global before every guest dispatch.
|
|
@@ -109,12 +116,6 @@ export class GlueRuntime {
|
|
|
109
116
|
}
|
|
110
117
|
/** The import object handed to `WebAssembly.instantiate`. Guest sees only these. */
|
|
111
118
|
buildImports(getExports) {
|
|
112
|
-
const mem = () => {
|
|
113
|
-
const ex = getExports();
|
|
114
|
-
if (!ex)
|
|
115
|
-
throw new Error('guest not instantiated');
|
|
116
|
-
return new DataView(ex.memory.buffer);
|
|
117
|
-
};
|
|
118
119
|
const bytesAt = (ptr, len) => {
|
|
119
120
|
const ex = getExports();
|
|
120
121
|
if (!ex)
|
|
@@ -139,8 +140,12 @@ export class GlueRuntime {
|
|
|
139
140
|
const randomFill = this.options.randomFill ?? defaultRandomFill;
|
|
140
141
|
const ck = {
|
|
141
142
|
log: (level, ptr, len) => {
|
|
143
|
+
const ex = getExports();
|
|
144
|
+
if (!ex)
|
|
145
|
+
throw new Error('guest not instantiated');
|
|
146
|
+
assertMemoryRange(ex.memory.buffer, ptr, len, 'guest log read');
|
|
142
147
|
if (this.options.onLog) {
|
|
143
|
-
this.options.onLog(level, textDecoder.decode(bytesAt(ptr, len)));
|
|
148
|
+
this.options.onLog(level, textDecoder.decode(bytesAt(ptr, Math.min(len, GLUE_LOG_MAX_BYTES))));
|
|
144
149
|
}
|
|
145
150
|
},
|
|
146
151
|
now_ms: () => BigInt(now()),
|
|
@@ -170,35 +175,19 @@ export class GlueRuntime {
|
|
|
170
175
|
return (BigInt(outPtr) << 32n) | BigInt(respBytes.length >>> 0);
|
|
171
176
|
},
|
|
172
177
|
};
|
|
173
|
-
const
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
return 0;
|
|
183
|
-
},
|
|
184
|
-
// A player artifact may pull in a few benign wasi stubs; keep them inert.
|
|
185
|
-
proc_exit: () => {
|
|
186
|
-
throw new Error('proc_exit called (guest trap)');
|
|
187
|
-
},
|
|
188
|
-
fd_write: () => 0,
|
|
189
|
-
environ_get: () => 0,
|
|
190
|
-
environ_sizes_get: (envcPtr, envBufSzPtr) => {
|
|
191
|
-
const dv = mem();
|
|
192
|
-
dv.setUint32(envcPtr, 0, true);
|
|
193
|
-
dv.setUint32(envBufSzPtr, 0, true);
|
|
194
|
-
return 0;
|
|
195
|
-
},
|
|
178
|
+
const random_get = (ptr, len) => {
|
|
179
|
+
const ex = getExports();
|
|
180
|
+
if (!ex)
|
|
181
|
+
throw new Error('guest not instantiated');
|
|
182
|
+
const buffer = ex.memory.buffer;
|
|
183
|
+
assertMemoryRange(buffer, ptr, len, 'random_get write');
|
|
184
|
+
const buf = new Uint8Array(buffer, ptr, len);
|
|
185
|
+
randomFill(buf);
|
|
186
|
+
return 0;
|
|
196
187
|
};
|
|
197
188
|
return {
|
|
198
189
|
ck,
|
|
199
|
-
wasi_snapshot_preview1:
|
|
200
|
-
// Some toolchains name the module `wasi_unstable`; alias defensively.
|
|
201
|
-
wasi_unstable: wasi,
|
|
190
|
+
wasi_snapshot_preview1: { random_get },
|
|
202
191
|
};
|
|
203
192
|
}
|
|
204
193
|
async instantiate(artifact) {
|
|
@@ -208,6 +197,12 @@ export class GlueRuntime {
|
|
|
208
197
|
if (!ex.memory || typeof ex.ck_alloc !== 'function') {
|
|
209
198
|
throw new Error('artifact is missing the ck ABI (memory / ck_alloc)');
|
|
210
199
|
}
|
|
200
|
+
if (!(ex.ck_fuel instanceof WebAssembly.Global)) {
|
|
201
|
+
throw new Error('a ck-exec CLIENT half must export the ck_fuel meter; it was not instrumented');
|
|
202
|
+
}
|
|
203
|
+
if (this.options.fuelPerDispatch == null) {
|
|
204
|
+
throw new Error('a ck-exec CLIENT half needs its fuel budget');
|
|
205
|
+
}
|
|
211
206
|
this.exports = ex;
|
|
212
207
|
}
|
|
213
208
|
/** Run the module's `init` export (once, after instantiate). */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The synchronous host-call transport for browser
|
|
3
|
-
*
|
|
2
|
+
* The synchronous host-call transport for a CLIENT half's browser WASM.
|
|
3
|
+
* WASM imports are synchronous, but the host-call
|
|
4
4
|
* handler (the server-authorized SDK path) is async and lives on the page,
|
|
5
5
|
* while the guest runs in a Worker. The only correct bridge is a
|
|
6
6
|
* SharedArrayBuffer the worker blocks on with `Atomics.wait`: the worker
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The synchronous host-call transport for browser
|
|
3
|
-
*
|
|
2
|
+
* The synchronous host-call transport for a CLIENT half's browser WASM.
|
|
3
|
+
* WASM imports are synchronous, but the host-call
|
|
4
4
|
* handler (the server-authorized SDK path) is async and lives on the page,
|
|
5
5
|
* while the guest runs in a Worker. The only correct bridge is a
|
|
6
6
|
* SharedArrayBuffer the worker blocks on with `Atomics.wait`: the worker
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { EXEC_CLIENT_HOST_CALLS } from './client-host-calls.js';
|
|
1
2
|
import { ClientGridEvent, ClientGridEventBus } from './client-grid-event-bus.js';
|
|
3
|
+
export { EXEC_CLIENT_HOST_CALLS };
|
|
2
4
|
export interface PlayerCodeGridBounds {
|
|
3
5
|
low: {
|
|
4
6
|
x: bigint;
|
|
@@ -12,8 +14,8 @@ export interface PlayerCodeGridBounds {
|
|
|
12
14
|
};
|
|
13
15
|
/**
|
|
14
16
|
* The grid's id. Required for the grid event bus (`emit_event` /
|
|
15
|
-
* `on_event`)
|
|
16
|
-
*
|
|
17
|
+
* `on_event`); a broker without it refuses those calls. With it, a
|
|
18
|
+
* `grid_permission_check` naming another grid is refused here.
|
|
17
19
|
*/
|
|
18
20
|
gridId?: string;
|
|
19
21
|
}
|
|
@@ -36,24 +38,69 @@ export interface PlayerCodePresentation {
|
|
|
36
38
|
channel: 'hud' | 'overlay';
|
|
37
39
|
payload: unknown;
|
|
38
40
|
}
|
|
41
|
+
/** crowdy-client-sdk's log levels: 0 debug, 1 info, 2 warn, 3 error. */
|
|
42
|
+
export type PlayerCodeLogLevel = 'debug' | 'info' | 'warn' | 'error';
|
|
43
|
+
/**
|
|
44
|
+
* One `crowdy::log` line of the running module, as the broker forwards it. The text is the
|
|
45
|
+
* module author's, so render it as text, never as markup.
|
|
46
|
+
*/
|
|
47
|
+
export interface PlayerCodeLogLine {
|
|
48
|
+
level: PlayerCodeLogLevel;
|
|
49
|
+
/** At most {@link PLAYER_CODE_LOG_MAX_CHARS} characters; a longer line ends in `…`. */
|
|
50
|
+
message: string;
|
|
51
|
+
/** The broker's `moduleName`, or null. */
|
|
52
|
+
moduleName: string | null;
|
|
53
|
+
}
|
|
54
|
+
/** Log lines forwarded per rolling second; past it lines are counted and dropped. */
|
|
55
|
+
export declare const PLAYER_CODE_LOG_LINES_PER_SECOND = 20;
|
|
56
|
+
/** The longest log line forwarded, in characters. */
|
|
57
|
+
export declare const PLAYER_CODE_LOG_MAX_CHARS = 1000;
|
|
58
|
+
/** The largest `invoke` payload, and the largest reply accepted, in bytes. */
|
|
59
|
+
export declare const PLAYER_CODE_INVOKE_MAX_BYTES: number;
|
|
60
|
+
/**
|
|
61
|
+
* What built a player module: the CLIENT half of a ck-exec mod, a `crowdy-client-sdk` crate.
|
|
62
|
+
* The only engine since 18.0 removed legacy player compute's CLIENT modules.
|
|
63
|
+
*/
|
|
64
|
+
export type PlayerCodeEngine = 'ck-exec';
|
|
39
65
|
export interface PlayerCodeBrokerOptions {
|
|
40
66
|
/** Platform-owned glue worker URL; the worker never receives auth tokens. */
|
|
41
67
|
workerUrl: string | URL;
|
|
42
68
|
grid: PlayerCodeGridBounds;
|
|
43
69
|
/**
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
70
|
+
* `'ck-exec'`, the only engine and the default: host calls are at most
|
|
71
|
+
* {@link EXEC_CLIENT_HOST_CALLS}, and the glue offers exactly the CLIENT ABI imports
|
|
72
|
+
* (`ck::{log,now_ms,state_get,state_set,host_call}` and
|
|
73
|
+
* `wasi_snapshot_preview1::random_get`) and refuses a module without the `ck_fuel` meter.
|
|
74
|
+
*/
|
|
75
|
+
engine?: PlayerCodeEngine;
|
|
76
|
+
/**
|
|
77
|
+
* The host calls the player consented to: the served CLIENT half's
|
|
78
|
+
* `capabilitySummary.hostFunctions`. A call outside it is refused like one outside the
|
|
79
|
+
* allowlist, so a module that assembles a host call's name at run time, which the build's
|
|
80
|
+
* summary cannot see, still reaches only what the player agreed to.
|
|
47
81
|
*/
|
|
48
|
-
|
|
82
|
+
consentedHostCalls: readonly string[];
|
|
49
83
|
/**
|
|
50
|
-
*
|
|
51
|
-
*
|
|
84
|
+
* Content hash (SHA-256, hex) of the platform-served artifact: start() refuses any artifact
|
|
85
|
+
* whose hash does not match, so a side-loaded module cannot run (09 T7). Pass the served
|
|
86
|
+
* CLIENT half's `digest`.
|
|
52
87
|
*/
|
|
53
|
-
|
|
88
|
+
artifactHash: string;
|
|
89
|
+
/**
|
|
90
|
+
* The served CLIENT half's per-dispatch fuel budget. The glue loads it into the module's
|
|
91
|
+
* `ck_fuel` meter before every dispatch; the build's instrument step is what enforces it.
|
|
92
|
+
*/
|
|
93
|
+
fuelPerDispatch: bigint;
|
|
54
94
|
onHostCall: (call: PlayerCodeHostCall) => Promise<unknown>;
|
|
55
95
|
/** Optional sink for HUD/overlay presentation the mod emits (BWF wires this). */
|
|
56
96
|
onPresentation?: (presentation: PlayerCodePresentation) => void;
|
|
97
|
+
/**
|
|
98
|
+
* Optional sink for the module's `crowdy::log` lines, at most
|
|
99
|
+
* {@link PLAYER_CODE_LOG_LINES_PER_SECOND} a second, each cut to
|
|
100
|
+
* {@link PLAYER_CODE_LOG_MAX_CHARS} characters. Past the rate, lines are dropped and the next
|
|
101
|
+
* line forwarded is preceded by a `warn` that counts them. Without a sink they are dropped.
|
|
102
|
+
*/
|
|
103
|
+
onLog?: (line: PlayerCodeLogLine) => void;
|
|
57
104
|
/** Called when the local circuit breaker trips (repeated traps / rate abuse). */
|
|
58
105
|
onCircuitOpen?: (reason: string) => void;
|
|
59
106
|
workerFactory?: (url: string | URL) => PlayerCodeWorkerLike;
|
|
@@ -83,26 +130,16 @@ export interface PlayerCodeBrokerOptions {
|
|
|
83
130
|
eventBus?: ClientGridEventBus | null;
|
|
84
131
|
}
|
|
85
132
|
/**
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
* and the capability summary are checked against). Only owner-lawful reads and
|
|
89
|
-
* effects cross the bridge; auth, admin, authoring, grid mutation, raw UDP
|
|
90
|
-
* pose, voice, teams, and any network fetch are absent by construction, not
|
|
91
|
-
* by a denylist. `grid_info` and `emit_event` are answered by the broker
|
|
92
|
-
* itself (the mod's own bounds; the page-local grid event bus).
|
|
93
|
-
*/
|
|
94
|
-
export declare const ALLOWED_HOST_CALLS: Readonly<Record<string, ReadonlySet<string>>>;
|
|
95
|
-
/**
|
|
96
|
-
* Page-side security broker for browser-target player WASM (production shape,
|
|
97
|
-
* player compute P3).
|
|
133
|
+
* Page-side security broker for a ck-exec mod's CLIENT half: browser WASM from one
|
|
134
|
+
* `crowdy-client-sdk` crate, built by the platform and served to a player who consented to it.
|
|
98
135
|
*
|
|
99
136
|
* The untrusted glue worker runs the player module; the broker is the trusted
|
|
100
137
|
* boundary on the page:
|
|
101
138
|
* - artifact bytes come only from the platform (hash-verified; side-load
|
|
102
|
-
* refused),
|
|
139
|
+
* refused) and are metered (`ck_fuel`, refilled per dispatch),
|
|
103
140
|
* - a deny-by-default, capability-grouped host-call allowlist crosses the
|
|
104
|
-
* bridge, each call re-validated
|
|
105
|
-
* filtered on both reads and effects,
|
|
141
|
+
* bridge, narrowed to what the player consented to, each call re-validated
|
|
142
|
+
* (confused-deputy safe) and grid-AABB filtered on both reads and effects,
|
|
106
143
|
* - per-call-family rate caps bound a runaway mod,
|
|
107
144
|
* - a local circuit breaker + per-dispatch watchdog recover the page from a
|
|
108
145
|
* hung or abusive worker.
|
|
@@ -129,8 +166,13 @@ export declare class PlayerCodeBroker {
|
|
|
129
166
|
private startupTimer;
|
|
130
167
|
private dispatchTimer;
|
|
131
168
|
private activeDispatch;
|
|
169
|
+
private readonly consented;
|
|
132
170
|
private busUnsubscribe;
|
|
133
171
|
private deliveringEventDepth;
|
|
172
|
+
private logBucket;
|
|
173
|
+
private droppedLogs;
|
|
174
|
+
private invokeSeq;
|
|
175
|
+
private readonly pendingInvokes;
|
|
134
176
|
private readonly busSubscriber;
|
|
135
177
|
constructor(options: PlayerCodeBrokerOptions);
|
|
136
178
|
/**
|
|
@@ -150,6 +192,17 @@ export declare class PlayerCodeBroker {
|
|
|
150
192
|
/** Terminate + respawn on a fresh artifact — the client hot-reload path. */
|
|
151
193
|
restart(artifact: ArrayBuffer): Promise<void>;
|
|
152
194
|
stop(): void;
|
|
195
|
+
/**
|
|
196
|
+
* Call the running module's `handle_invoke` export with `payload` and resolve with the bytes
|
|
197
|
+
* it returns. The page chooses the payload; the reply is the module's, so treat it as
|
|
198
|
+
* untrusted input. Refused while the module is not running, above
|
|
199
|
+
* {@link PLAYER_CODE_INVOKE_MAX_BYTES}, or with eight invokes already pending; rejected when
|
|
200
|
+
* the module traps, stops or does not answer within `timeoutMs` (default 10 s). Each invoke is
|
|
201
|
+
* one dispatch, on the same fuel budget and watchdog as a tick.
|
|
202
|
+
*/
|
|
203
|
+
invoke(payload: Uint8Array, options?: {
|
|
204
|
+
timeoutMs?: number;
|
|
205
|
+
}): Promise<Uint8Array>;
|
|
153
206
|
/** Clear a tripped circuit so the caller can start again after a fix. */
|
|
154
207
|
resetCircuit(): void;
|
|
155
208
|
private handleMessage;
|
|
@@ -164,6 +217,9 @@ export declare class PlayerCodeBroker {
|
|
|
164
217
|
*/
|
|
165
218
|
private reply;
|
|
166
219
|
private spawnWorker;
|
|
220
|
+
private settleInvoke;
|
|
221
|
+
/** Forward one worker log line within the rate and size bounds; a sink that throws is ignored. */
|
|
222
|
+
private forwardLog;
|
|
167
223
|
private stopWorker;
|
|
168
224
|
private armStartupTimer;
|
|
169
225
|
private clearStartupTimer;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"player-code-broker.d.ts","sourceRoot":"","sources":["../../src/player-runtime/player-code-broker.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"player-code-broker.d.ts","sourceRoot":"","sources":["../../src/player-runtime/player-code-broker.ts"],"names":[],"mappings":"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"}
|