@crowdedkingdoms/crowdyjs 17.14.0-dev.1 → 18.0.1-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 +129 -1
- package/README.md +97 -164
- 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 +34 -59
- package/dist/crowdy-studio/controller.d.ts.map +1 -1
- package/dist/crowdy-studio/controller.js +96 -225
- 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 -49
- package/dist/crowdy-studio/embed/hud-layer.d.ts +1 -2
- package/dist/crowdy-studio/embed/hud-layer.d.ts.map +1 -1
- package/dist/crowdy-studio/embed/panel.d.ts +3 -13
- 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 -12
- package/dist/crowdy-studio/starter-projects.d.ts.map +1 -1
- package/dist/crowdy-studio/starter-projects.js +12 -103
- 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/apps.d.ts +1 -10
- package/dist/domains/apps.d.ts.map +1 -1
- package/dist/domains/apps.js +1 -16
- package/dist/domains/host.d.ts +3 -3
- package/dist/domains/host.js +3 -3
- package/dist/domains/hosting.d.ts +0 -6
- package/dist/domains/hosting.d.ts.map +1 -1
- package/dist/domains/hosting.js +1 -16
- package/dist/domains/marketplace.d.ts +9 -70
- package/dist/domains/marketplace.d.ts.map +1 -1
- package/dist/domains/marketplace.js +9 -120
- package/dist/domains/organizations.d.ts +1 -9
- package/dist/domains/organizations.d.ts.map +1 -1
- package/dist/domains/organizations.js +1 -15
- package/dist/domains/payments.d.ts +5 -48
- package/dist/domains/payments.d.ts.map +1 -1
- package/dist/domains/payments.js +5 -57
- 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/domains/quotas.d.ts +20 -7
- package/dist/domains/quotas.d.ts.map +1 -1
- package/dist/domains/quotas.js +15 -6
- package/dist/domains/users.d.ts +7 -74
- package/dist/domains/users.d.ts.map +1 -1
- package/dist/domains/users.js +7 -105
- 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 +955 -8272
- package/dist/generated/graphql.d.ts.map +1 -1
- package/dist/generated/graphql.js +5 -329
- package/dist/grid-mods/exec-client-halves.d.ts +19 -3
- package/dist/grid-mods/exec-client-halves.d.ts.map +1 -1
- package/dist/grid-mods/exec-client-halves.js +17 -2
- package/dist/grid-mods/grid-host-calls.d.ts +29 -17
- package/dist/grid-mods/grid-host-calls.d.ts.map +1 -1
- package/dist/grid-mods/grid-host-calls.js +40 -46
- package/dist/grid-mods/mod-runtime.d.ts +18 -11
- package/dist/grid-mods/mod-runtime.d.ts.map +1 -1
- package/dist/grid-mods/mod-runtime.js +4 -2
- package/dist/grid-scope.d.ts +0 -189
- package/dist/grid-scope.d.ts.map +1 -1
- package/dist/grid-scope.js +0 -70
- package/dist/index.d.ts +12 -18
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -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 +30 -34
- 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 +24 -20
- package/dist/player-runtime/glue-runtime.d.ts.map +1 -1
- package/dist/player-runtime/glue-runtime.js +26 -55
- 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 +70 -43
- package/dist/player-runtime/player-code-broker.d.ts.map +1 -1
- package/dist/player-runtime/player-code-broker.js +159 -64
- package/dist/player-runtime/player-glue-worker.d.ts +8 -9
- package/dist/player-runtime/player-glue-worker.d.ts.map +1 -1
- package/dist/player-runtime/player-glue-worker.js +26 -11
- 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 targetSnippets(target
|
|
135
|
+
for (const snippet of targetSnippets(target))
|
|
136
136
|
add(snippet);
|
|
137
137
|
}
|
|
138
138
|
for (const symbol of this.platformIndex.symbols) {
|
|
@@ -255,35 +255,31 @@ export class RustAnalysis {
|
|
|
255
255
|
}
|
|
256
256
|
}
|
|
257
257
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
const snippets = TARGET_SNIPPETS[target];
|
|
261
|
-
if (target !== 'client' || !text.includes('crowdy_client_sdk'))
|
|
262
|
-
return snippets;
|
|
263
|
-
return snippets.map((snippet) => snippet.insertText?.includes('crowdy_compute_sdk::')
|
|
264
|
-
? {
|
|
265
|
-
...snippet,
|
|
266
|
-
insertText: snippet.insertText.replace('crowdy_compute_sdk::', 'crowdy_client_sdk::'),
|
|
267
|
-
}
|
|
268
|
-
: snippet);
|
|
258
|
+
function targetSnippets(target) {
|
|
259
|
+
return TARGET_SNIPPETS[target];
|
|
269
260
|
}
|
|
270
261
|
function targetForDocument(document) {
|
|
271
262
|
const first = document.path.split('/', 1)[0]?.toLowerCase();
|
|
272
263
|
return first === 'server' || first === 'client' ? first : null;
|
|
273
264
|
}
|
|
265
|
+
const SERVER_LIFECYCLE = ['spawn', 'load', 'persist', 'handle', 'on_world', 'on_timer'];
|
|
266
|
+
const CLIENT_LIFECYCLE = ['init', 'tick', 'invoke', 'event'];
|
|
274
267
|
function targetLifecycleNote(document, word) {
|
|
275
268
|
const target = targetForDocument(document);
|
|
276
|
-
if (
|
|
277
|
-
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.';
|
|
278
273
|
}
|
|
279
|
-
if (target === '
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
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.';
|
|
283
281
|
}
|
|
284
|
-
return
|
|
285
|
-
? 'CLIENT ticks execute inside the browser guest sandbox only when PlayerCodeBroker.tickIntervalMs is set; all page effects cross the PlayerCodeBroker allow-list.'
|
|
286
|
-
: 'CLIENT lifecycle code is loaded from the exact hash-bound artifact produced for this project version.';
|
|
282
|
+
return null;
|
|
287
283
|
}
|
|
288
284
|
function visit(node, callback) {
|
|
289
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,21 +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
|
-
*
|
|
11
|
-
* `
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* `
|
|
16
|
-
*
|
|
17
|
-
* must export the `ck_fuel` meter; a legacy module also gets inert wasi
|
|
18
|
-
* stubs and the `wasi_unstable` alias.
|
|
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
|
+
* `host_call(ptr,len) -> u64` (packed `resp_ptr<<32 | resp_len`, guest frees
|
|
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)`.
|
|
19
17
|
*
|
|
20
18
|
* `host_call` is SYNCHRONOUS from the guest's view. The single synchronous
|
|
21
19
|
* dependency this core takes is `hostCallSync(reqBytes) -> respBytes`; the
|
|
@@ -23,17 +21,19 @@
|
|
|
23
21
|
* (the worker blocks; the page/broker services the async SDK call and writes
|
|
24
22
|
* the reply back). Everything else here is pure.
|
|
25
23
|
*/
|
|
26
|
-
/** The host-call names
|
|
24
|
+
/** The host-call names a guest may send: the broker's allowlist, {@link EXEC_CLIENT_HOST_CALLS}. */
|
|
27
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
28
|
/** Every import a ck-exec CLIENT half may have (CLIENT ABI 0), by module. */
|
|
29
29
|
export declare const EXEC_CLIENT_ABI_IMPORTS: Readonly<Record<string, readonly string[]>>;
|
|
30
30
|
export interface GlueInitMessage {
|
|
31
31
|
type: 'init';
|
|
32
32
|
artifact: ArrayBuffer;
|
|
33
33
|
authority: 'player';
|
|
34
|
-
/**
|
|
35
|
-
engine?: '
|
|
36
|
-
/** Server-authored budget loaded into
|
|
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. */
|
|
37
37
|
fuelPerDispatch?: string;
|
|
38
38
|
/** Legacy metadata; the hard watchdog is owned by the page-side broker. */
|
|
39
39
|
watchdogMs?: number;
|
|
@@ -76,17 +76,21 @@ export interface GuestExports {
|
|
|
76
76
|
export interface GlueRuntimeOptions {
|
|
77
77
|
/** Synchronous host-API gateway: JSON request bytes in, SDK Response-envelope bytes out. */
|
|
78
78
|
hostCallSync: (reqBytes: Uint8Array) => Uint8Array;
|
|
79
|
-
/**
|
|
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
|
+
*/
|
|
80
83
|
onLog?: (level: number, message: string) => void;
|
|
81
84
|
/** Deterministic-enough randomness for the guest `random_get` (defaults to crypto). */
|
|
82
85
|
randomFill?: (buf: Uint8Array) => void;
|
|
83
86
|
now?: () => number;
|
|
87
|
+
/** The per-dispatch budget; a module is refused without one. */
|
|
84
88
|
fuelPerDispatch?: bigint | null;
|
|
85
89
|
/**
|
|
86
|
-
* `'ck-exec'
|
|
87
|
-
* export the `ck_fuel` meter, or a missing budget.
|
|
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.
|
|
88
92
|
*/
|
|
89
|
-
engine?: '
|
|
93
|
+
engine?: 'ck-exec';
|
|
90
94
|
}
|
|
91
95
|
/**
|
|
92
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,21 +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
|
-
*
|
|
11
|
-
* `
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* `
|
|
16
|
-
*
|
|
17
|
-
* must export the `ck_fuel` meter; a legacy module also gets inert wasi
|
|
18
|
-
* stubs and the `wasi_unstable` alias.
|
|
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
|
+
* `host_call(ptr,len) -> u64` (packed `resp_ptr<<32 | resp_len`, guest frees
|
|
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)`.
|
|
19
17
|
*
|
|
20
18
|
* `host_call` is SYNCHRONOUS from the guest's view. The single synchronous
|
|
21
19
|
* dependency this core takes is `hostCallSync(reqBytes) -> respBytes`; the
|
|
@@ -23,11 +21,11 @@
|
|
|
23
21
|
* (the worker blocks; the page/broker services the async SDK call and writes
|
|
24
22
|
* the reply back). Everything else here is pure.
|
|
25
23
|
*/
|
|
26
|
-
import {
|
|
27
|
-
/** The host-call names
|
|
28
|
-
export const GLUE_HOST_FUNCTIONS =
|
|
29
|
-
|
|
30
|
-
|
|
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;
|
|
31
29
|
/** Every import a ck-exec CLIENT half may have (CLIENT ABI 0), by module. */
|
|
32
30
|
export const EXEC_CLIENT_ABI_IMPORTS = {
|
|
33
31
|
ck: ['log', 'now_ms', 'state_get', 'state_set', 'host_call'],
|
|
@@ -118,12 +116,6 @@ export class GlueRuntime {
|
|
|
118
116
|
}
|
|
119
117
|
/** The import object handed to `WebAssembly.instantiate`. Guest sees only these. */
|
|
120
118
|
buildImports(getExports) {
|
|
121
|
-
const mem = () => {
|
|
122
|
-
const ex = getExports();
|
|
123
|
-
if (!ex)
|
|
124
|
-
throw new Error('guest not instantiated');
|
|
125
|
-
return new DataView(ex.memory.buffer);
|
|
126
|
-
};
|
|
127
119
|
const bytesAt = (ptr, len) => {
|
|
128
120
|
const ex = getExports();
|
|
129
121
|
if (!ex)
|
|
@@ -148,8 +140,12 @@ export class GlueRuntime {
|
|
|
148
140
|
const randomFill = this.options.randomFill ?? defaultRandomFill;
|
|
149
141
|
const ck = {
|
|
150
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');
|
|
151
147
|
if (this.options.onLog) {
|
|
152
|
-
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))));
|
|
153
149
|
}
|
|
154
150
|
},
|
|
155
151
|
now_ms: () => BigInt(now()),
|
|
@@ -189,32 +185,9 @@ export class GlueRuntime {
|
|
|
189
185
|
randomFill(buf);
|
|
190
186
|
return 0;
|
|
191
187
|
};
|
|
192
|
-
if (this.options.engine === 'ck-exec') {
|
|
193
|
-
return {
|
|
194
|
-
ck,
|
|
195
|
-
wasi_snapshot_preview1: { random_get },
|
|
196
|
-
};
|
|
197
|
-
}
|
|
198
|
-
const wasi = {
|
|
199
|
-
random_get,
|
|
200
|
-
// A player artifact may pull in a few benign wasi stubs; keep them inert.
|
|
201
|
-
proc_exit: () => {
|
|
202
|
-
throw new Error('proc_exit called (guest trap)');
|
|
203
|
-
},
|
|
204
|
-
fd_write: () => 0,
|
|
205
|
-
environ_get: () => 0,
|
|
206
|
-
environ_sizes_get: (envcPtr, envBufSzPtr) => {
|
|
207
|
-
const dv = mem();
|
|
208
|
-
dv.setUint32(envcPtr, 0, true);
|
|
209
|
-
dv.setUint32(envBufSzPtr, 0, true);
|
|
210
|
-
return 0;
|
|
211
|
-
},
|
|
212
|
-
};
|
|
213
188
|
return {
|
|
214
189
|
ck,
|
|
215
|
-
wasi_snapshot_preview1:
|
|
216
|
-
// Some toolchains name the module `wasi_unstable`; alias defensively.
|
|
217
|
-
wasi_unstable: wasi,
|
|
190
|
+
wasi_snapshot_preview1: { random_get },
|
|
218
191
|
};
|
|
219
192
|
}
|
|
220
193
|
async instantiate(artifact) {
|
|
@@ -224,13 +197,11 @@ export class GlueRuntime {
|
|
|
224
197
|
if (!ex.memory || typeof ex.ck_alloc !== 'function') {
|
|
225
198
|
throw new Error('artifact is missing the ck ABI (memory / ck_alloc)');
|
|
226
199
|
}
|
|
227
|
-
if (
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
throw new Error('a ck-exec CLIENT half needs its fuel budget');
|
|
233
|
-
}
|
|
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');
|
|
234
205
|
}
|
|
235
206
|
this.exports = ex;
|
|
236
207
|
}
|
|
@@ -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,46 +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';
|
|
39
43
|
/**
|
|
40
|
-
*
|
|
41
|
-
*
|
|
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.
|
|
42
46
|
*/
|
|
43
|
-
export
|
|
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';
|
|
44
65
|
export interface PlayerCodeBrokerOptions {
|
|
45
66
|
/** Platform-owned glue worker URL; the worker never receives auth tokens. */
|
|
46
67
|
workerUrl: string | URL;
|
|
47
68
|
grid: PlayerCodeGridBounds;
|
|
48
69
|
/**
|
|
49
|
-
* `'ck-exec'
|
|
50
|
-
* {@link EXEC_CLIENT_HOST_CALLS}, the glue offers exactly the CLIENT ABI imports
|
|
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
|
|
51
72
|
* (`ck::{log,now_ms,state_get,state_set,host_call}` and
|
|
52
|
-
* `wasi_snapshot_preview1::random_get`)
|
|
53
|
-
* `fuelPerDispatch` or {@link consentedHostCalls} does not start. `'player-compute'` (the
|
|
54
|
-
* default until 18.0) keeps a legacy
|
|
55
|
-
* CLIENT module's whole {@link ALLOWED_HOST_CALLS} and import table.
|
|
73
|
+
* `wasi_snapshot_preview1::random_get`) and refuses a module without the `ck_fuel` meter.
|
|
56
74
|
*/
|
|
57
75
|
engine?: PlayerCodeEngine;
|
|
58
76
|
/**
|
|
59
77
|
* The host calls the player consented to: the served CLIENT half's
|
|
60
|
-
* `capabilitySummary.hostFunctions`.
|
|
61
|
-
*
|
|
62
|
-
*
|
|
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.
|
|
63
81
|
*/
|
|
64
|
-
consentedHostCalls
|
|
82
|
+
consentedHostCalls: readonly string[];
|
|
65
83
|
/**
|
|
66
|
-
* Content hash of the platform-
|
|
67
|
-
*
|
|
68
|
-
*
|
|
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`.
|
|
69
87
|
*/
|
|
70
|
-
artifactHash
|
|
88
|
+
artifactHash: string;
|
|
71
89
|
/**
|
|
72
|
-
*
|
|
73
|
-
*
|
|
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.
|
|
74
92
|
*/
|
|
75
|
-
fuelPerDispatch
|
|
93
|
+
fuelPerDispatch: bigint;
|
|
76
94
|
onHostCall: (call: PlayerCodeHostCall) => Promise<unknown>;
|
|
77
95
|
/** Optional sink for HUD/overlay presentation the mod emits (BWF wires this). */
|
|
78
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;
|
|
79
104
|
/** Called when the local circuit breaker trips (repeated traps / rate abuse). */
|
|
80
105
|
onCircuitOpen?: (reason: string) => void;
|
|
81
106
|
workerFactory?: (url: string | URL) => PlayerCodeWorkerLike;
|
|
@@ -105,32 +130,16 @@ export interface PlayerCodeBrokerOptions {
|
|
|
105
130
|
eventBus?: ClientGridEventBus | null;
|
|
106
131
|
}
|
|
107
132
|
/**
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
* and the capability summary are checked against). Only owner-lawful reads and
|
|
111
|
-
* effects cross the bridge; auth, admin, authoring, grid mutation, raw UDP
|
|
112
|
-
* pose, voice, teams, and any network fetch are absent by construction, not
|
|
113
|
-
* by a denylist. `grid_info` and `emit_event` are answered by the broker
|
|
114
|
-
* itself (the mod's own bounds; the page-local grid event bus).
|
|
115
|
-
*/
|
|
116
|
-
export declare const ALLOWED_HOST_CALLS: Readonly<Record<string, ReadonlySet<string>>>;
|
|
117
|
-
/**
|
|
118
|
-
* The host calls a ck-exec mod's CLIENT half may make, grouped as {@link ALLOWED_HOST_CALLS}:
|
|
119
|
-
* the client half of the host catalog less what only the legacy engines answer (the `model`
|
|
120
|
-
* group, `sessions_list` and `grid_state_*`). It is exactly what crowdy-client-sdk wraps.
|
|
121
|
-
*/
|
|
122
|
-
export declare const EXEC_CLIENT_HOST_CALLS: Readonly<Record<string, ReadonlySet<string>>>;
|
|
123
|
-
/**
|
|
124
|
-
* Page-side security broker for browser-target player WASM (production shape,
|
|
125
|
-
* 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.
|
|
126
135
|
*
|
|
127
136
|
* The untrusted glue worker runs the player module; the broker is the trusted
|
|
128
137
|
* boundary on the page:
|
|
129
138
|
* - artifact bytes come only from the platform (hash-verified; side-load
|
|
130
|
-
* refused),
|
|
139
|
+
* refused) and are metered (`ck_fuel`, refilled per dispatch),
|
|
131
140
|
* - a deny-by-default, capability-grouped host-call allowlist crosses the
|
|
132
|
-
* bridge, each call re-validated
|
|
133
|
-
* 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,
|
|
134
143
|
* - per-call-family rate caps bound a runaway mod,
|
|
135
144
|
* - a local circuit breaker + per-dispatch watchdog recover the page from a
|
|
136
145
|
* hung or abusive worker.
|
|
@@ -160,6 +169,10 @@ export declare class PlayerCodeBroker {
|
|
|
160
169
|
private readonly consented;
|
|
161
170
|
private busUnsubscribe;
|
|
162
171
|
private deliveringEventDepth;
|
|
172
|
+
private logBucket;
|
|
173
|
+
private droppedLogs;
|
|
174
|
+
private invokeSeq;
|
|
175
|
+
private readonly pendingInvokes;
|
|
163
176
|
private readonly busSubscriber;
|
|
164
177
|
constructor(options: PlayerCodeBrokerOptions);
|
|
165
178
|
/**
|
|
@@ -179,6 +192,17 @@ export declare class PlayerCodeBroker {
|
|
|
179
192
|
/** Terminate + respawn on a fresh artifact — the client hot-reload path. */
|
|
180
193
|
restart(artifact: ArrayBuffer): Promise<void>;
|
|
181
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>;
|
|
182
206
|
/** Clear a tripped circuit so the caller can start again after a fix. */
|
|
183
207
|
resetCircuit(): void;
|
|
184
208
|
private handleMessage;
|
|
@@ -193,6 +217,9 @@ export declare class PlayerCodeBroker {
|
|
|
193
217
|
*/
|
|
194
218
|
private reply;
|
|
195
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;
|
|
196
223
|
private stopWorker;
|
|
197
224
|
private armStartupTimer;
|
|
198
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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"}
|