@moku-labs/game 0.8.0 → 0.10.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 +88 -26
- package/bin/moku-game.mjs +4 -0
- package/dist/app/page.d.mts +41 -0
- package/dist/app/page.mjs +376 -0
- package/dist/app/system.d.mts +129 -0
- package/dist/app/system.mjs +307 -0
- package/dist/app.d.mts +37 -0
- package/dist/app.mjs +235 -0
- package/dist/assets-BHwTLVta.mjs +7391 -0
- package/dist/assets.d.mts +97 -33
- package/dist/assets.mjs +1 -7150
- package/dist/{capture-BX5Gfoty.mjs → capture-fpd83Mi5.mjs} +384 -1
- package/dist/cli.d.mts +70 -0
- package/dist/cli.mjs +1650 -0
- package/dist/{commands-C1kIfOG5.d.mts → commands-C4QlqijJ.d.mts} +5 -6
- package/dist/config-CdARrrhU.mjs +81 -0
- package/dist/control.d.mts +11 -10
- package/dist/control.mjs +3 -3
- package/dist/{define-BPpZcpxW.d.mts → define-CCc0ozKe.d.mts} +2 -2
- package/dist/{dev-wKLgOw7c.mjs → dev-Cc50Dk7H.mjs} +1 -1
- package/dist/{memory-CvgdnsQO.mjs → drafts-BawpSaVp.mjs} +1 -104
- package/dist/fake-MpzwZhIZ.mjs +87 -0
- package/dist/{headless-CvamCUcR.mjs → headless-BsNdJs9W.mjs} +1 -1
- package/dist/{headless-q98SwADR.d.mts → headless-G4nuZ-xz.d.mts} +1 -1
- package/dist/hot.d.mts +8 -8
- package/dist/hot.mjs +15 -14
- package/dist/index-xxSxKJJW.d.mts +1611 -0
- package/dist/index.d.mts +6 -1597
- package/dist/index.mjs +4 -34343
- package/dist/inspect-la_KkjCS.mjs +1 -0
- package/dist/inspect.d.mts +7 -8
- package/dist/inspect.mjs +3 -2
- package/dist/jsx-dev-runtime.d.mts +1 -1
- package/dist/jsx-runtime.d.mts +1 -1
- package/dist/lint.d.mts +55 -4
- package/dist/lint.mjs +999 -42
- package/dist/memory-CWlqhS7l.mjs +136 -0
- package/dist/memory-DwDhfFWK.d.mts +50 -0
- package/dist/project.d.mts +29 -13
- package/dist/project.mjs +1120 -631
- package/dist/{run-CUPSFM85.mjs → run-wYty_Lwo.mjs} +4 -4
- package/dist/{runtime-CvDZZg1S.d.mts → runtime-DOBYM6g4.d.mts} +1 -1
- package/dist/{input-z_35Jwfn.mjs → session-DgukhR_7.mjs} +20 -20
- package/dist/{sources-BBUd15vQ.mjs → sources-Duzj6lhV.mjs} +3 -3
- package/dist/src-DSl1eNB1.mjs +34366 -0
- package/dist/testing.d.mts +115 -34
- package/dist/testing.mjs +175 -70
- package/dist/{types-DlgsfOmW.d.mts → types-BM4shh8K.d.mts} +300 -263
- package/dist/{types-DgdMLZnV.d.mts → types-BUwDHKXm.d.mts} +1372 -1373
- package/dist/{types-DF5kkW-C.d.mts → types-CefgYzFt.d.mts} +4 -5
- package/dist/{types-CDSKa0vl.d.mts → types-DAdwEJMp.d.mts} +2 -2
- package/dist/{types-BWzCSRM2.d.mts → types-ZQLYXo5X.d.mts} +2983 -20
- package/dist/types-hQgI_wrq.d.mts +544 -0
- package/dist/{visual-DUvvPPCt.mjs → visual-dMW8iqAE.mjs} +8 -4
- package/dist/visual.d.mts +10 -11
- package/dist/visual.mjs +5 -5
- package/llms.txt +170 -57
- package/package.json +30 -2
- package/dist/registry-DlpRCibU.mjs +0 -384
- package/dist/types-ERb2Y9U5.d.mts +0 -2967
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { b as AnimApi, p as ScenesApi, t as AudioApi, v as UiApi } from "./types-DlgsfOmW.mjs";
|
|
1
|
+
import { A as Api$2, E as DebugSwitches, Ot as Bookmark, h as Api$1, jt as FlowState, ln as Api, vn as Time, w as Captured } from "./types-ZQLYXo5X.mjs";
|
|
2
|
+
import { a as AudioApi, r as UiApi, v as ScenesApi, x as AnimApi } from "./types-BM4shh8K.mjs";
|
|
3
|
+
import { A as InputApi } from "./types-BUwDHKXm.mjs";
|
|
4
|
+
import { t as HeadlessApp } from "./headless-G4nuZ-xz.mjs";
|
|
5
|
+
import { n as Command, r as ControlApp } from "./types-DAdwEJMp.mjs";
|
|
7
6
|
|
|
8
7
|
//#region src/plugins/flow/doors/commands.d.ts
|
|
9
8
|
/**
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
//#region src/app/config.ts
|
|
2
|
+
/**
|
|
3
|
+
* The save kinds a config may name.
|
|
4
|
+
*
|
|
5
|
+
* @returns The set of save kinds.
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* saveKinds().has("disk"); // false
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
11
|
+
function saveKinds() {
|
|
12
|
+
return /* @__PURE__ */ new Set([
|
|
13
|
+
"memory",
|
|
14
|
+
"local",
|
|
15
|
+
"store"
|
|
16
|
+
]);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* The system plugins the game shell wires, by their `@moku-labs/system` names.
|
|
20
|
+
*
|
|
21
|
+
* @returns The set of system names.
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* systemNames().has("keepAwake"); // true
|
|
25
|
+
* systemNames().has("tray"); // false
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
function systemNames() {
|
|
29
|
+
return /* @__PURE__ */ new Set([
|
|
30
|
+
"lifecycle",
|
|
31
|
+
"back",
|
|
32
|
+
"haptics",
|
|
33
|
+
"keepAwake",
|
|
34
|
+
"store"
|
|
35
|
+
]);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Throws for the first value of a config that TypeScript would have refused.
|
|
39
|
+
*
|
|
40
|
+
* @param config - The default export of `config.ts`.
|
|
41
|
+
* @throws {Error} When `save` is not a save kind, a `system` name is not wired, or the title is empty.
|
|
42
|
+
*/
|
|
43
|
+
function checkConfig(config) {
|
|
44
|
+
if (config.save !== void 0 && !saveKinds().has(config.save)) throw new Error(`[game] config.save is "${config.save}".\n Use "memory", "local" or "store".`);
|
|
45
|
+
const wired = systemNames();
|
|
46
|
+
const unwired = config.system?.find((name) => !wired.has(name));
|
|
47
|
+
if (unwired !== void 0) throw new Error(`[game] config.system names "${unwired}", which the game shell does not wire.\n Use lifecycle, back, haptics, keepAwake or store.`);
|
|
48
|
+
if (config.page.title.trim() === "") throw new Error("[game] config.page.title is empty.\n Give the page a title in config.ts.");
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Fills every default of a game's `config.ts`: `lang` `"en"`, `background` `"#000000"`,
|
|
52
|
+
* `orientation` `"portrait"`, no icons, no head tags, no system plugin, the memory save, no asset
|
|
53
|
+
* layers.
|
|
54
|
+
*
|
|
55
|
+
* @param config - The default export of `config.ts`.
|
|
56
|
+
* @returns The config with every field set.
|
|
57
|
+
* @throws {Error} When `save` is not a save kind, a `system` name is not wired, or the title is empty.
|
|
58
|
+
* @example
|
|
59
|
+
* ```ts
|
|
60
|
+
* resolveConfig({ page: { title: "T" } }).save; // "memory"
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
function resolveConfig(config) {
|
|
64
|
+
checkConfig(config);
|
|
65
|
+
return {
|
|
66
|
+
page: {
|
|
67
|
+
title: config.page.title,
|
|
68
|
+
lang: config.page.lang ?? "en",
|
|
69
|
+
background: config.page.background ?? "#000000",
|
|
70
|
+
orientation: config.page.orientation ?? "portrait",
|
|
71
|
+
icons: config.page.icons ?? {},
|
|
72
|
+
head: config.page.head ?? []
|
|
73
|
+
},
|
|
74
|
+
native: config.native,
|
|
75
|
+
system: config.system ?? [],
|
|
76
|
+
save: config.save ?? "memory",
|
|
77
|
+
assets: { layers: config.assets?.layers ?? {} }
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
//#endregion
|
|
81
|
+
export { resolveConfig as t };
|
package/dist/control.d.mts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { t as HeadlessApp } from "./headless-
|
|
2
|
-
import { i as InputArguments, n as Command, o as InputSchema, s as Ran } from "./types-
|
|
3
|
-
import { t as commands } from "./commands-
|
|
4
|
-
import { t as defineCommand } from "./define-
|
|
1
|
+
import { t as HeadlessApp } from "./headless-G4nuZ-xz.mjs";
|
|
2
|
+
import { i as InputArguments, n as Command, o as InputSchema, s as Ran } from "./types-DAdwEJMp.mjs";
|
|
3
|
+
import { t as commands } from "./commands-C4QlqijJ.mjs";
|
|
4
|
+
import { t as defineCommand } from "./define-CCc0ozKe.mjs";
|
|
5
5
|
|
|
6
6
|
//#region src/plugins/flow/doors/dev.d.ts
|
|
7
7
|
/**
|
|
8
8
|
* @file flow/doors — the dev flag and the errors a door throws. `__MOKU_GAME_DEV__` is a global
|
|
9
|
-
* the engine never replaces:
|
|
10
|
-
* `globalThis.__MOKU_GAME_DEV__` before the engine runs;
|
|
9
|
+
* the engine never replaces: `moku-game dev` defines it `true` (bunfig `define`) and sets
|
|
10
|
+
* `globalThis.__MOKU_GAME_DEV__` in `.moku/dev.ts` before the engine runs; `moku-game build`
|
|
11
|
+
* defines it `false`; undefined means a production build.
|
|
11
12
|
*
|
|
12
13
|
* Bun does not inline `isDev()` across modules (checked on Bun 1.3.14), so a branch that must
|
|
13
14
|
* vanish from a production bundle writes the guard inline:
|
|
@@ -16,12 +17,12 @@ import { t as defineCommand } from "./define-BPpZcpxW.mjs";
|
|
|
16
17
|
*/
|
|
17
18
|
declare global {
|
|
18
19
|
/**
|
|
19
|
-
* The dev flag of a game. A game never re-declares it:
|
|
20
|
-
* `
|
|
20
|
+
* The dev flag of a game. A game never re-declares it: `moku-game dev` sets it, `moku-game
|
|
21
|
+
* build` defines it `false`, and a test stubs it.
|
|
21
22
|
*
|
|
22
23
|
* @example
|
|
23
24
|
* ```ts
|
|
24
|
-
* //
|
|
25
|
+
* // .moku/dev.ts, written by moku-game dev, the first import of the dev page: /control commands run from here on.
|
|
25
26
|
* globalThis.__MOKU_GAME_DEV__ = true;
|
|
26
27
|
* ```
|
|
27
28
|
*/
|
|
@@ -33,7 +34,7 @@ declare global {
|
|
|
33
34
|
* @returns True only when `__MOKU_GAME_DEV__` is exactly `true`.
|
|
34
35
|
* @example
|
|
35
36
|
* ```ts
|
|
36
|
-
* // The dev page set the flag in
|
|
37
|
+
* // The dev page set the flag in .moku/dev.ts before the engine started.
|
|
37
38
|
* globalThis.__MOKU_GAME_DEV__ = true;
|
|
38
39
|
* isDev(); // true
|
|
39
40
|
* ```
|
package/dist/control.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as controlRefused } from "./dev-
|
|
2
|
-
import { s as defineCommand } from "./
|
|
3
|
-
import { n as commands, t as run } from "./run-
|
|
1
|
+
import { t as controlRefused } from "./dev-Cc50Dk7H.mjs";
|
|
2
|
+
import { s as defineCommand } from "./session-DgukhR_7.mjs";
|
|
3
|
+
import { n as commands, t as run } from "./run-wYty_Lwo.mjs";
|
|
4
4
|
export { commands, controlRefused, defineCommand, run };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { t as HeadlessApp } from "./headless-
|
|
2
|
-
import { c as Source, n as Command, o as InputSchema } from "./types-
|
|
1
|
+
import { t as HeadlessApp } from "./headless-G4nuZ-xz.mjs";
|
|
2
|
+
import { c as Source, n as Command, o as InputSchema } from "./types-DAdwEJMp.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/plugins/flow/doors/define.d.ts
|
|
5
5
|
/**
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* @returns True only when `__MOKU_GAME_DEV__` is exactly `true`.
|
|
6
6
|
* @example
|
|
7
7
|
* ```ts
|
|
8
|
-
* // The dev page set the flag in
|
|
8
|
+
* // The dev page set the flag in .moku/dev.ts before the engine started.
|
|
9
9
|
* globalThis.__MOKU_GAME_DEV__ = true;
|
|
10
10
|
* isDev(); // true
|
|
11
11
|
* ```
|
|
@@ -153,107 +153,4 @@ function dropDrafts(pair) {
|
|
|
153
153
|
finishDraft(pair);
|
|
154
154
|
}
|
|
155
155
|
//#endregion
|
|
156
|
-
|
|
157
|
-
/** Seed of a save built by `saveOf` when the caller does not pin one. */
|
|
158
|
-
const defaultSeed = 1;
|
|
159
|
-
/** The base a patch applies to when the provider was never handed a document. */
|
|
160
|
-
const noDocument = {};
|
|
161
|
-
/**
|
|
162
|
-
* Creates an in-memory provider that keeps what it was committed and records every call.
|
|
163
|
-
* It is the default when a game configures no `playerProvider`, and the double every test uses:
|
|
164
|
-
* `provider.calls` is the whole persistence protocol of one run, in order. The document lives as
|
|
165
|
-
* long as the provider does, so a second app over the same instance reads what the first one
|
|
166
|
-
* wrote, and nothing survives the process.
|
|
167
|
-
*
|
|
168
|
-
* `load()` reads the fixture, or everything committed since; without either, the player is new.
|
|
169
|
-
* `commitDurable()` resolves at once: there is no disk behind it.
|
|
170
|
-
*
|
|
171
|
-
* @param fixture - The save `load()` starts from. Omitted: a new player.
|
|
172
|
-
* @param fixture.state - The saved document.
|
|
173
|
-
* @param fixture.version - Schema version of the saved document.
|
|
174
|
-
* @returns A provider that keeps its document and records its calls.
|
|
175
|
-
* @example
|
|
176
|
-
* ```ts
|
|
177
|
-
* // A new player is saved at once. One roll reaches the provider at the next rest node.
|
|
178
|
-
* const provider = memory();
|
|
179
|
-
* const game = await createHeadless(createGame(provider));
|
|
180
|
-
*
|
|
181
|
-
* await game.walk([{ at: "home", intent: "roll" }]);
|
|
182
|
-
* provider.calls.map(call => call.method); // ["load", "commit", "commit"]
|
|
183
|
-
* ```
|
|
184
|
-
*/
|
|
185
|
-
function memory(fixture) {
|
|
186
|
-
const calls = [];
|
|
187
|
-
const held = {
|
|
188
|
-
document: fixture?.state,
|
|
189
|
-
version: fixture?.version ?? 0
|
|
190
|
-
};
|
|
191
|
-
/**
|
|
192
|
-
* Applies the patches of one commit to the held document.
|
|
193
|
-
*
|
|
194
|
-
* @param patches - Doc patches since the last commit.
|
|
195
|
-
* @param version - Schema version this build writes.
|
|
196
|
-
* @throws {Error} When a patch names a path the held document does not have.
|
|
197
|
-
*/
|
|
198
|
-
const hold = (patches, version) => {
|
|
199
|
-
held.document = applyTo(held.document ?? noDocument, patches);
|
|
200
|
-
held.version = version;
|
|
201
|
-
};
|
|
202
|
-
return {
|
|
203
|
-
calls,
|
|
204
|
-
load: async () => {
|
|
205
|
-
calls.push({ method: "load" });
|
|
206
|
-
const document = held.document;
|
|
207
|
-
if (document === void 0) return null;
|
|
208
|
-
return {
|
|
209
|
-
state: document,
|
|
210
|
-
version: held.version
|
|
211
|
-
};
|
|
212
|
-
},
|
|
213
|
-
commit: (patches, version) => {
|
|
214
|
-
calls.push({
|
|
215
|
-
method: "commit",
|
|
216
|
-
patches,
|
|
217
|
-
version
|
|
218
|
-
});
|
|
219
|
-
hold(patches, version);
|
|
220
|
-
},
|
|
221
|
-
commitDurable: async (patches, txId, version) => {
|
|
222
|
-
calls.push({
|
|
223
|
-
method: "commitDurable",
|
|
224
|
-
patches,
|
|
225
|
-
txId,
|
|
226
|
-
version
|
|
227
|
-
});
|
|
228
|
-
hold(patches, version);
|
|
229
|
-
},
|
|
230
|
-
flush: async () => {
|
|
231
|
-
calls.push({ method: "flush" });
|
|
232
|
-
}
|
|
233
|
-
};
|
|
234
|
-
}
|
|
235
|
-
/**
|
|
236
|
-
* Builds a save document from a player tree, with no rng streams drawn yet.
|
|
237
|
-
* Short fixtures in tests read as `saveOf({ coins: 5 })` instead of spelling out the rng branch.
|
|
238
|
-
*
|
|
239
|
-
* @param player - Player tree of the save.
|
|
240
|
-
* @param seed - Rng seed of the save.
|
|
241
|
-
* @returns The save document.
|
|
242
|
-
* @example
|
|
243
|
-
* ```ts
|
|
244
|
-
* // A returning player with 5 coins. The test starts from this save, not from `initialPlayer`.
|
|
245
|
-
* saveOf({ coins: 5 }, 42); // { player: { coins: 5 }, rng: { seed: 42, streams: {} } }
|
|
246
|
-
* const provider = memory({ state: saveOf({ coins: 5 }, 42), version: 1 });
|
|
247
|
-
* ```
|
|
248
|
-
*/
|
|
249
|
-
function saveOf(player, seed = defaultSeed) {
|
|
250
|
-
return {
|
|
251
|
-
player,
|
|
252
|
-
rng: {
|
|
253
|
-
seed,
|
|
254
|
-
streams: {}
|
|
255
|
-
}
|
|
256
|
-
};
|
|
257
|
-
}
|
|
258
|
-
//#endregion
|
|
259
|
-
export { enableDraftPatches as a, dropDrafts as i, saveOf as n, finishDrafts as o, deepFreeze as r, openDrafts as s, memory as t };
|
|
156
|
+
export { finishDrafts as a, enableDraftPatches as i, deepFreeze as n, openDrafts as o, dropDrafts as r, applyTo as t };
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
//#region src/plugins/clock/fake.ts
|
|
2
|
+
/**
|
|
3
|
+
* Removes and returns the timer that is due first, up to and including `until`.
|
|
4
|
+
* Timers due at the same moment come out in the order they were scheduled.
|
|
5
|
+
*
|
|
6
|
+
* @param state - Innards of the fake clock.
|
|
7
|
+
* @param until - Latest moment that counts as due.
|
|
8
|
+
* @returns The timer to fire, or `undefined` when nothing is due.
|
|
9
|
+
*/
|
|
10
|
+
function takeDue(state, until) {
|
|
11
|
+
let earliest;
|
|
12
|
+
for (const timer of state.timers) {
|
|
13
|
+
if (timer.at > until) continue;
|
|
14
|
+
if (earliest === void 0 || timer.at < earliest.at) earliest = timer;
|
|
15
|
+
}
|
|
16
|
+
if (earliest === void 0) return void 0;
|
|
17
|
+
const due = earliest;
|
|
18
|
+
state.timers = state.timers.filter((timer) => timer !== due);
|
|
19
|
+
return due;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Moves the clock to `until`, firing every timer that falls due on the way, in due order.
|
|
23
|
+
* A timer scheduled inside a callback fires in the same run when it is due before `until`.
|
|
24
|
+
*
|
|
25
|
+
* @param state - Innards of the fake clock.
|
|
26
|
+
* @param until - Moment to stop at.
|
|
27
|
+
*/
|
|
28
|
+
function runDue(state, until) {
|
|
29
|
+
let due = takeDue(state, until);
|
|
30
|
+
while (due !== void 0) {
|
|
31
|
+
state.now = Math.max(state.now, due.at);
|
|
32
|
+
due.callback();
|
|
33
|
+
due = takeDue(state, until);
|
|
34
|
+
}
|
|
35
|
+
state.now = Math.max(state.now, until);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Creates a fake source for tests. Timers fire synchronously inside `advance`, in due order. A
|
|
39
|
+
* negative delay counts as zero and an unknown handle is ignored.
|
|
40
|
+
*
|
|
41
|
+
* @param start - Starting moment in epoch milliseconds. Defaults to 0.
|
|
42
|
+
* @returns A clock source with the test-only controls `advance` and `set`.
|
|
43
|
+
* @example
|
|
44
|
+
* ```ts
|
|
45
|
+
* // An energy point refills 60 s after it was spent. The test moves the clock, not the minute.
|
|
46
|
+
* const clock = fakeClock(1000);
|
|
47
|
+
* const app = createApp({ pluginConfigs: { clock: { source: clock } } });
|
|
48
|
+
* const seen: number[] = [];
|
|
49
|
+
*
|
|
50
|
+
* app.clock.onElapsed(({ now }) => seen.push(now));
|
|
51
|
+
* app.clock.scheduleAt(61_000);
|
|
52
|
+
* clock.advance(60_000); // the timer fires inside advance, nothing waits
|
|
53
|
+
* seen; // [61000]
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
function fakeClock(start = 0) {
|
|
57
|
+
const state = {
|
|
58
|
+
now: start,
|
|
59
|
+
nextId: 1,
|
|
60
|
+
timers: []
|
|
61
|
+
};
|
|
62
|
+
return {
|
|
63
|
+
now: () => state.now,
|
|
64
|
+
setTimer: (callback, delayMs) => {
|
|
65
|
+
const id = state.nextId;
|
|
66
|
+
state.nextId += 1;
|
|
67
|
+
state.timers.push({
|
|
68
|
+
id,
|
|
69
|
+
at: state.now + Math.max(0, delayMs),
|
|
70
|
+
callback
|
|
71
|
+
});
|
|
72
|
+
return id;
|
|
73
|
+
},
|
|
74
|
+
clearTimer: (handle) => {
|
|
75
|
+
if (typeof handle !== "number") return;
|
|
76
|
+
state.timers = state.timers.filter((timer) => timer.id !== handle);
|
|
77
|
+
},
|
|
78
|
+
advance: (ms) => {
|
|
79
|
+
runDue(state, state.now + Math.max(0, ms));
|
|
80
|
+
},
|
|
81
|
+
set: (moment) => {
|
|
82
|
+
state.now = moment;
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
//#endregion
|
|
87
|
+
export { fakeClock as t };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Bt as Answer, Mt as JournalEntry, Pt as RouteStep, Xt as Json, cn as RngState, dt as Api$1, hn as Api, jt as FlowState } from "./types-ZQLYXo5X.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/plugins/flow/headless.d.ts
|
|
4
4
|
/**
|
package/dist/hot.d.mts
CHANGED
|
@@ -14,8 +14,10 @@
|
|
|
14
14
|
type HotOptions = {
|
|
15
15
|
/**
|
|
16
16
|
* The files that get the footer. Default: `.tsx` files, `styles.ts`, `view.ts`,
|
|
17
|
-
* `animations.ts`, `effects.ts
|
|
18
|
-
*
|
|
17
|
+
* `animations.ts`, `effects.ts`, any `.ts` directly in a `styles/`, `motion/`, `effects/` or
|
|
18
|
+
* `views/` folder, and in `world/projections/` or `world/layout/`, and
|
|
19
|
+
* `generated/strings.<locale>.ts`. Bun runs it as the load filter on the absolute path, so it
|
|
20
|
+
* should not anchor at the start.
|
|
19
21
|
*/
|
|
20
22
|
include?: RegExp;
|
|
21
23
|
/**
|
|
@@ -70,16 +72,14 @@ type HotPlugin = {
|
|
|
70
72
|
* @returns The Bun plugin object.
|
|
71
73
|
* @example
|
|
72
74
|
* ```ts
|
|
73
|
-
* // bunfig.toml
|
|
74
|
-
* //
|
|
75
|
-
* //
|
|
76
|
-
* // A game that keeps its views in `look/` folders exports its own plugin from `hot.ts`
|
|
77
|
-
* // and lists `plugins = ["./hot.ts"]` instead:
|
|
75
|
+
* // `moku-game dev` lists the default plugin in `.moku/bunfig.toml`: a game sets nothing.
|
|
76
|
+
* // A game with a server of its own and its views in `look/` folders exports its own plugin
|
|
77
|
+
* // from `hot.ts` and lists `plugins = ["./hot.ts"]` in its own bunfig.toml:
|
|
78
78
|
* export default hot({ include: /\/look\/.*\.ts$/ });
|
|
79
79
|
* ```
|
|
80
80
|
*/
|
|
81
81
|
declare function hot(options?: HotOptions): HotPlugin;
|
|
82
|
-
/** The Bun plugin with the default filters,
|
|
82
|
+
/** The Bun plugin with the default filters: the one `moku-game dev` lists, or `plugins = ["@moku-labs/game/hot"]` in a game's own `bunfig.toml`. */
|
|
83
83
|
declare const _default: HotPlugin;
|
|
84
84
|
//#endregion
|
|
85
85
|
export { HotBuild, HotOptions, HotPlugin, _default as default, hot };
|
package/dist/hot.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { readFile } from "node:fs/promises";
|
|
2
1
|
import path from "node:path";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
3
|
//#region src/hot.ts
|
|
4
4
|
/**
|
|
5
5
|
* @file Hot entry (subpath `./hot`): the Bun plugin of the dev server that hot swaps the views of
|
|
@@ -7,16 +7,19 @@ import path from "node:path";
|
|
|
7
7
|
* update and hands the new exports to the running game through `globalThis.__moku_hot`. The `ui`
|
|
8
8
|
* plugin installs that handler in dev builds only. What swaps: styles, components, projections,
|
|
9
9
|
* animations, text styles, emitters and generated strings. A view module is a `.tsx` file, a
|
|
10
|
-
* `styles.ts`, a `view.ts`, an `animations.ts`, an `effects.ts`
|
|
11
|
-
* `
|
|
12
|
-
*
|
|
13
|
-
*
|
|
10
|
+
* `styles.ts`, a `view.ts`, an `animations.ts`, an `effects.ts`, any `.ts` directly in a
|
|
11
|
+
* `styles/`, `motion/`, `effects/` or `views/` folder, any `.ts` directly in `world/projections/`
|
|
12
|
+
* or `world/layout/`, or a generated `generated/strings.<locale>.ts`; a logic module never gets
|
|
13
|
+
* the footer (`world/components/` and `world/systems/` included: they are registered at start), so
|
|
14
|
+
* its save reaches the root and the page reloads and restores its state. `moku-game dev` lists the
|
|
15
|
+
* plugin first in `[serve.static]` of the bunfig it writes, `.moku/bunfig.toml`; a game without the
|
|
16
|
+
* shell lists it in its own `bunfig.toml`. The dev server only: `moku-game build` never loads it.
|
|
14
17
|
*/
|
|
15
18
|
/**
|
|
16
|
-
* The default view modules:
|
|
17
|
-
*
|
|
19
|
+
* The default view modules: the view files by name or by kind folder. Two literals joined, so
|
|
20
|
+
* each stays readable.
|
|
18
21
|
*/
|
|
19
|
-
const DEFAULT_INCLUDE =
|
|
22
|
+
const DEFAULT_INCLUDE = new RegExp(`(${/\.tsx|\/styles\.ts|\/view\.ts|\/animations\.ts|\/effects\.ts|\/generated\/strings\.[\w-]+\.ts/.source}|${/\/(?:styles|motion|effects|views)\/[^/]+\.ts|\/world\/(?:projections|layout)\/[^/]+\.ts/.source})$`);
|
|
20
23
|
/** The generated strings of one locale, the one file under `generated/` that swaps. */
|
|
21
24
|
const STRINGS = /\/generated\/strings\.[\w-]+\.ts$/;
|
|
22
25
|
/** The default folders and test files that never hot swap. The outer group only scopes the `$`. */
|
|
@@ -71,11 +74,9 @@ function footerOf(file) {
|
|
|
71
74
|
* @returns The Bun plugin object.
|
|
72
75
|
* @example
|
|
73
76
|
* ```ts
|
|
74
|
-
* // bunfig.toml
|
|
75
|
-
* //
|
|
76
|
-
* //
|
|
77
|
-
* // A game that keeps its views in `look/` folders exports its own plugin from `hot.ts`
|
|
78
|
-
* // and lists `plugins = ["./hot.ts"]` instead:
|
|
77
|
+
* // `moku-game dev` lists the default plugin in `.moku/bunfig.toml`: a game sets nothing.
|
|
78
|
+
* // A game with a server of its own and its views in `look/` folders exports its own plugin
|
|
79
|
+
* // from `hot.ts` and lists `plugins = ["./hot.ts"]` in its own bunfig.toml:
|
|
79
80
|
* export default hot({ include: /\/look\/.*\.ts$/ });
|
|
80
81
|
* ```
|
|
81
82
|
*/
|
|
@@ -102,7 +103,7 @@ function hot(options = {}) {
|
|
|
102
103
|
}
|
|
103
104
|
};
|
|
104
105
|
}
|
|
105
|
-
/** The Bun plugin with the default filters,
|
|
106
|
+
/** The Bun plugin with the default filters: the one `moku-game dev` lists, or `plugins = ["@moku-labs/game/hot"]` in a game's own `bunfig.toml`. */
|
|
106
107
|
var hot_default = hot();
|
|
107
108
|
//#endregion
|
|
108
109
|
export { hot_default as default, hot };
|