@datamoc/mw_games 0.31.0 → 0.33.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.
Files changed (62) hide show
  1. package/CHANGELOG.md +67 -0
  2. package/api-surface.json +312 -0
  3. package/dist/assets/index.d.ts +2 -0
  4. package/dist/assets/index.d.ts.map +1 -1
  5. package/dist/assets/index.js +1 -0
  6. package/dist/assets/index.js.map +1 -1
  7. package/dist/assets/svg.d.ts +87 -0
  8. package/dist/assets/svg.d.ts.map +1 -0
  9. package/dist/assets/svg.js +162 -0
  10. package/dist/assets/svg.js.map +1 -0
  11. package/dist/index.d.ts +1 -0
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +1 -0
  14. package/dist/index.js.map +1 -1
  15. package/dist/mw_games.global.js +41 -41
  16. package/dist/mwl/fengari.d.ts +12 -6
  17. package/dist/mwl/fengari.d.ts.map +1 -1
  18. package/dist/mwl/fengari.js +56 -70
  19. package/dist/mwl/fengari.js.map +1 -1
  20. package/dist/mwl/runtime.d.ts +13 -0
  21. package/dist/mwl/runtime.d.ts.map +1 -1
  22. package/dist/mwl/runtime.js +72 -4
  23. package/dist/mwl/runtime.js.map +1 -1
  24. package/dist/mwl/schema.d.ts.map +1 -1
  25. package/dist/mwl/schema.js +4 -1
  26. package/dist/mwl/schema.js.map +1 -1
  27. package/dist/roguelike/Cave.d.ts +109 -0
  28. package/dist/roguelike/Cave.d.ts.map +1 -0
  29. package/dist/roguelike/Cave.js +192 -0
  30. package/dist/roguelike/Cave.js.map +1 -0
  31. package/dist/roguelike/Overworld.d.ts +82 -0
  32. package/dist/roguelike/Overworld.d.ts.map +1 -0
  33. package/dist/roguelike/Overworld.js +306 -0
  34. package/dist/roguelike/Overworld.js.map +1 -0
  35. package/dist/roguelike/index.d.ts +4 -0
  36. package/dist/roguelike/index.d.ts.map +1 -1
  37. package/dist/roguelike/index.js +2 -0
  38. package/dist/roguelike/index.js.map +1 -1
  39. package/dist/skeleton/index.d.ts +131 -0
  40. package/dist/skeleton/index.d.ts.map +1 -0
  41. package/dist/skeleton/index.js +206 -0
  42. package/dist/skeleton/index.js.map +1 -0
  43. package/dist/testing/SceneControls.d.ts +35 -0
  44. package/dist/testing/SceneControls.d.ts.map +1 -0
  45. package/dist/testing/SceneControls.js +49 -0
  46. package/dist/testing/SceneControls.js.map +1 -0
  47. package/dist/testing/index.d.ts +2 -0
  48. package/dist/testing/index.d.ts.map +1 -1
  49. package/dist/testing/index.js +1 -0
  50. package/dist/testing/index.js.map +1 -1
  51. package/dist/two-d/render/SkeletalSprite.d.ts +118 -0
  52. package/dist/two-d/render/SkeletalSprite.d.ts.map +1 -0
  53. package/dist/two-d/render/SkeletalSprite.js +189 -0
  54. package/dist/two-d/render/SkeletalSprite.js.map +1 -0
  55. package/dist/two-d/render/index.d.ts +2 -0
  56. package/dist/two-d/render/index.d.ts.map +1 -1
  57. package/dist/two-d/render/index.js +1 -0
  58. package/dist/two-d/render/index.js.map +1 -1
  59. package/dist/version.d.ts +1 -1
  60. package/dist/version.js +1 -1
  61. package/package.json +7 -2
  62. package/sbom.cdx.json +222 -222
package/CHANGELOG.md CHANGED
@@ -7,6 +7,73 @@ the public API may still change between minor versions.
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.33.0] - 2026-10-10
11
+
12
+ Seven roadmap items in one release: the Wesnoth port's proposal file is now fully answered
13
+ (405 shipped with 0.32.0, 406/407/409 this release, 408's first half, 401 parked with the
14
+ port), alongside the skeletal puppet pair (399/400), SVG as inbound data (398), the overworld
15
+ generator (410), and the Lua host riding the fork's new allocation hook.
16
+
17
+ ### Added
18
+
19
+ - `skeleton`, a new renderer-free root module (roadmap 399): a bone tree where a pose is one
20
+ rotation per bone, keyframed clips (plain JSON, interpolation, looping, playback rate,
21
+ crossfade), and additive layers mixing by priority that displace only the bones they name.
22
+ `two-d/render` gains the drawing half (400): `SkeletalSprite` binds parts to bones by
23
+ name, and `ArticulatedChain`/`ChainRig` draw a follower-rule spine with per-segment
24
+ rotation limits.
25
+ - `roguelike.generateCave` (407): chambers grown as blobs (`jagged`), winding passages
26
+ (`windiness`, `width`, `chance`), starts with cleared rings, village density, and a forced
27
+ join so a cave is always connected. `roguelike.generateOverworld` (410): seeded elevation
28
+ and moisture fields classify seven terrains behind a `seaLevel` knob, rivers run downhill
29
+ to the sea and drown lakes at ridges, settlements place themselves by suitability and join
30
+ into a road tree that prefers flat ground (water a ford, not a wall), points of interest
31
+ carry `leadsTo`, and every cell carries a coarse region id.
32
+ - `assets` SVG inbound rules (398): `sanitizeSvg` refuses what it cannot prove inert by name,
33
+ `svgScaleVariants` rasterizes one source per named scale, `splitSvgGroups` loads one part
34
+ per top-level `<g>` group.
35
+ - `testing` gains `createSceneControls` (408's first half): named steps a game opts into,
36
+ driven by name, refused by name when unknown - the seam a headless driver calls a game's
37
+ private scene flow through.
38
+
39
+ ### Changed
40
+
41
+ - `mwl/fengari` now requires `@datamoc/fengari@^0.2.0` and enforces `memoryLimit` through the
42
+ fork's per-state allocation hook (`lua_setallocf`) instead of swapping the global
43
+ `Uint8Array` constructor mid-call: no global mutation (and so no reentrancy hazard between
44
+ hosts on one page), parsing is inside the budget, host callbacks allocate freely, and a
45
+ refused allocation surfaces to scripts as Lua's standard `not enough memory` while the
46
+ host still rejects the call.
47
+ - MWL `test=` expressions can call `have_unit`/`have_location` and registered predicate hooks
48
+ directly (406), `[while]` traces `while_limit` when its cap is reached with the condition
49
+ still true (`on_limit=error` makes it a hard failure), and `[condition]` accepts free
50
+ predicate attributes.
51
+
52
+ ## [0.32.0] - 2026-10-10
53
+
54
+ The optional Lua host hardens around what the `@datamoc/fengari` fork offers, and the
55
+ phantom-leader bug the Wesnoth port's scenarios exposed is fixed.
56
+
57
+ ### Changed
58
+
59
+ - `mwl/fengari` moves to the `@datamoc/fengari` fork (Lua 5.4) and opens only the
60
+ sandbox-safe Lua standard libraries (base, coroutine, math, string, table, utf8) through
61
+ the fork's `luaL_openselectedlibs`: `io`, `os`, `debug` and `package` with its `require`
62
+ are never constructed - identically in Node and the browser - instead of being opened and
63
+ then nil'd. Chunks now compile in text mode, so a binary `\x1bLua` dump is rejected instead
64
+ of reaching the bytecode undumper.
65
+ - Roadmap item 390 (the tourney chess engine) is closed by accepting its recorded split:
66
+ 4-piece tablebases stay a `tools/build-tablebases.mjs` run away rather than shipping tens
67
+ of megabytes per ending; the compiled 3-piece tables stay under `data/tablebases`.
68
+
69
+ ### Fixed
70
+
71
+ - `MwlRuntime` no longer spawns a phantom leader when a `[side]`'s `leader=` names an
72
+ already-declared unit: the named unit is the leader, a known unit type still spawns one
73
+ leader per free start cell with its real stats, and a value that is neither is refused by
74
+ name instead of creating a 1-hp, 0-move ghost (roadmap 405, which broke about ten of the
75
+ Wesnoth port's scenarios with "unknown unit type").
76
+
10
77
  ## [0.31.0] - 2026-10-09
11
78
 
12
79
  Two pixel-dungeon proposals: P43, `SpriteMotion` (squash, hop, bob, wobble, spin, shear and flip over `Tweener`, reduced-motion aware), and P42, camera snapping in whole device pixels, which closes the thin tile seams at a fractional `devicePixelRatio`.
package/api-surface.json CHANGED
@@ -131,6 +131,12 @@
131
131
  "subpath": ".",
132
132
  "declaringModule": "two-d/render/ImageModifiers.d.ts"
133
133
  },
134
+ {
135
+ "name": "ArticulatedChain",
136
+ "kind": "class",
137
+ "subpath": ".",
138
+ "declaringModule": "two-d/render/SkeletalSprite.d.ts"
139
+ },
134
140
  {
135
141
  "name": "assertAutotileLayout",
136
142
  "kind": "function",
@@ -383,6 +389,18 @@
383
389
  "subpath": ".",
384
390
  "declaringModule": "core/Grid.d.ts"
385
391
  },
392
+ {
393
+ "name": "ChainOptions",
394
+ "kind": "interface",
395
+ "subpath": ".",
396
+ "declaringModule": "two-d/render/SkeletalSprite.d.ts"
397
+ },
398
+ {
399
+ "name": "ChainRig",
400
+ "kind": "class",
401
+ "subpath": ".",
402
+ "declaringModule": "two-d/render/SkeletalSprite.d.ts"
403
+ },
386
404
  {
387
405
  "name": "channelScaleMatrix",
388
406
  "kind": "function",
@@ -2645,6 +2663,18 @@
2645
2663
  "subpath": ".",
2646
2664
  "declaringModule": "core/Sanitize.d.ts"
2647
2665
  },
2666
+ {
2667
+ "name": "SkeletalSprite",
2668
+ "kind": "class",
2669
+ "subpath": ".",
2670
+ "declaringModule": "two-d/render/SkeletalSprite.d.ts"
2671
+ },
2672
+ {
2673
+ "name": "Skeleton",
2674
+ "kind": "namespace",
2675
+ "subpath": ".",
2676
+ "declaringModule": "index.d.ts"
2677
+ },
2648
2678
  {
2649
2679
  "name": "Skin",
2650
2680
  "kind": "interface",
@@ -4733,6 +4763,18 @@
4733
4763
  "subpath": "./assets",
4734
4764
  "declaringModule": "assets/paths.d.ts"
4735
4765
  },
4766
+ {
4767
+ "name": "sanitizeSvg",
4768
+ "kind": "function",
4769
+ "subpath": "./assets",
4770
+ "declaringModule": "assets/svg.d.ts"
4771
+ },
4772
+ {
4773
+ "name": "ScaleVariant",
4774
+ "kind": "interface",
4775
+ "subpath": "./assets",
4776
+ "declaringModule": "assets/svg.d.ts"
4777
+ },
4736
4778
  {
4737
4779
  "name": "setAssetMap",
4738
4780
  "kind": "function",
@@ -4745,6 +4787,30 @@
4745
4787
  "subpath": "./assets",
4746
4788
  "declaringModule": "assets/paths.d.ts"
4747
4789
  },
4790
+ {
4791
+ "name": "splitSvgGroups",
4792
+ "kind": "function",
4793
+ "subpath": "./assets",
4794
+ "declaringModule": "assets/svg.d.ts"
4795
+ },
4796
+ {
4797
+ "name": "svgDataUri",
4798
+ "kind": "function",
4799
+ "subpath": "./assets",
4800
+ "declaringModule": "assets/svg.d.ts"
4801
+ },
4802
+ {
4803
+ "name": "svgScaleVariants",
4804
+ "kind": "function",
4805
+ "subpath": "./assets",
4806
+ "declaringModule": "assets/svg.d.ts"
4807
+ },
4808
+ {
4809
+ "name": "SvgVariant",
4810
+ "kind": "interface",
4811
+ "subpath": "./assets",
4812
+ "declaringModule": "assets/svg.d.ts"
4813
+ },
4748
4814
  {
4749
4815
  "name": "texture",
4750
4816
  "kind": "function",
@@ -9011,6 +9077,36 @@
9011
9077
  "subpath": "./roguelike",
9012
9078
  "declaringModule": "roguelike/Targeting.d.ts"
9013
9079
  },
9080
+ {
9081
+ "name": "CaveChamber",
9082
+ "kind": "interface",
9083
+ "subpath": "./roguelike",
9084
+ "declaringModule": "roguelike/Cave.d.ts"
9085
+ },
9086
+ {
9087
+ "name": "CaveOptions",
9088
+ "kind": "interface",
9089
+ "subpath": "./roguelike",
9090
+ "declaringModule": "roguelike/Cave.d.ts"
9091
+ },
9092
+ {
9093
+ "name": "CavePassage",
9094
+ "kind": "interface",
9095
+ "subpath": "./roguelike",
9096
+ "declaringModule": "roguelike/Cave.d.ts"
9097
+ },
9098
+ {
9099
+ "name": "CaveResult",
9100
+ "kind": "interface",
9101
+ "subpath": "./roguelike",
9102
+ "declaringModule": "roguelike/Cave.d.ts"
9103
+ },
9104
+ {
9105
+ "name": "CaveStart",
9106
+ "kind": "interface",
9107
+ "subpath": "./roguelike",
9108
+ "declaringModule": "roguelike/Cave.d.ts"
9109
+ },
9014
9110
  {
9015
9111
  "name": "CellFeatureDef",
9016
9112
  "kind": "interface",
@@ -9197,6 +9293,12 @@
9197
9293
  "subpath": "./roguelike",
9198
9294
  "declaringModule": "roguelike/generate.d.ts"
9199
9295
  },
9296
+ {
9297
+ "name": "generateCave",
9298
+ "kind": "function",
9299
+ "subpath": "./roguelike",
9300
+ "declaringModule": "roguelike/Cave.d.ts"
9301
+ },
9200
9302
  {
9201
9303
  "name": "generateDungeon",
9202
9304
  "kind": "function",
@@ -9209,6 +9311,12 @@
9209
9311
  "subpath": "./roguelike",
9210
9312
  "declaringModule": "roguelike/generate.d.ts"
9211
9313
  },
9314
+ {
9315
+ "name": "generateOverworld",
9316
+ "kind": "function",
9317
+ "subpath": "./roguelike",
9318
+ "declaringModule": "roguelike/Overworld.d.ts"
9319
+ },
9212
9320
  {
9213
9321
  "name": "hallBuilder",
9214
9322
  "kind": "const",
@@ -9287,6 +9395,36 @@
9287
9395
  "subpath": "./roguelike",
9288
9396
  "declaringModule": "roguelike/Level.d.ts"
9289
9397
  },
9398
+ {
9399
+ "name": "OverworldInterest",
9400
+ "kind": "interface",
9401
+ "subpath": "./roguelike",
9402
+ "declaringModule": "roguelike/Overworld.d.ts"
9403
+ },
9404
+ {
9405
+ "name": "OverworldOptions",
9406
+ "kind": "interface",
9407
+ "subpath": "./roguelike",
9408
+ "declaringModule": "roguelike/Overworld.d.ts"
9409
+ },
9410
+ {
9411
+ "name": "OverworldResult",
9412
+ "kind": "interface",
9413
+ "subpath": "./roguelike",
9414
+ "declaringModule": "roguelike/Overworld.d.ts"
9415
+ },
9416
+ {
9417
+ "name": "OverworldSettlement",
9418
+ "kind": "interface",
9419
+ "subpath": "./roguelike",
9420
+ "declaringModule": "roguelike/Overworld.d.ts"
9421
+ },
9422
+ {
9423
+ "name": "OverworldTerrain",
9424
+ "kind": "type",
9425
+ "subpath": "./roguelike",
9426
+ "declaringModule": "roguelike/Overworld.d.ts"
9427
+ },
9290
9428
  {
9291
9429
  "name": "Pathfinder",
9292
9430
  "kind": "class",
@@ -10151,6 +10289,120 @@
10151
10289
  "subpath": "./simulation",
10152
10290
  "declaringModule": "simulation/Runtime.d.ts"
10153
10291
  },
10292
+ {
10293
+ "name": "advance",
10294
+ "kind": "function",
10295
+ "subpath": "./skeleton",
10296
+ "declaringModule": "skeleton/index.d.ts"
10297
+ },
10298
+ {
10299
+ "name": "advancePlayback",
10300
+ "kind": "function",
10301
+ "subpath": "./skeleton",
10302
+ "declaringModule": "skeleton/index.d.ts"
10303
+ },
10304
+ {
10305
+ "name": "Bone",
10306
+ "kind": "interface",
10307
+ "subpath": "./skeleton",
10308
+ "declaringModule": "skeleton/index.d.ts"
10309
+ },
10310
+ {
10311
+ "name": "boneOrder",
10312
+ "kind": "function",
10313
+ "subpath": "./skeleton",
10314
+ "declaringModule": "skeleton/index.d.ts"
10315
+ },
10316
+ {
10317
+ "name": "BoneTransform",
10318
+ "kind": "interface",
10319
+ "subpath": "./skeleton",
10320
+ "declaringModule": "skeleton/index.d.ts"
10321
+ },
10322
+ {
10323
+ "name": "Clip",
10324
+ "kind": "interface",
10325
+ "subpath": "./skeleton",
10326
+ "declaringModule": "skeleton/index.d.ts"
10327
+ },
10328
+ {
10329
+ "name": "create",
10330
+ "kind": "function",
10331
+ "subpath": "./skeleton",
10332
+ "declaringModule": "skeleton/index.d.ts"
10333
+ },
10334
+ {
10335
+ "name": "createMixer",
10336
+ "kind": "function",
10337
+ "subpath": "./skeleton",
10338
+ "declaringModule": "skeleton/index.d.ts"
10339
+ },
10340
+ {
10341
+ "name": "crossfadeTo",
10342
+ "kind": "function",
10343
+ "subpath": "./skeleton",
10344
+ "declaringModule": "skeleton/index.d.ts"
10345
+ },
10346
+ {
10347
+ "name": "Keyframe",
10348
+ "kind": "interface",
10349
+ "subpath": "./skeleton",
10350
+ "declaringModule": "skeleton/index.d.ts"
10351
+ },
10352
+ {
10353
+ "name": "Layer",
10354
+ "kind": "interface",
10355
+ "subpath": "./skeleton",
10356
+ "declaringModule": "skeleton/index.d.ts"
10357
+ },
10358
+ {
10359
+ "name": "Mixer",
10360
+ "kind": "interface",
10361
+ "subpath": "./skeleton",
10362
+ "declaringModule": "skeleton/index.d.ts"
10363
+ },
10364
+ {
10365
+ "name": "mixPoses",
10366
+ "kind": "function",
10367
+ "subpath": "./skeleton",
10368
+ "declaringModule": "skeleton/index.d.ts"
10369
+ },
10370
+ {
10371
+ "name": "Playback",
10372
+ "kind": "interface",
10373
+ "subpath": "./skeleton",
10374
+ "declaringModule": "skeleton/index.d.ts"
10375
+ },
10376
+ {
10377
+ "name": "Pose",
10378
+ "kind": "type",
10379
+ "subpath": "./skeleton",
10380
+ "declaringModule": "skeleton/index.d.ts"
10381
+ },
10382
+ {
10383
+ "name": "resolve",
10384
+ "kind": "function",
10385
+ "subpath": "./skeleton",
10386
+ "declaringModule": "skeleton/index.d.ts"
10387
+ },
10388
+ {
10389
+ "name": "samplePose",
10390
+ "kind": "function",
10391
+ "subpath": "./skeleton",
10392
+ "declaringModule": "skeleton/index.d.ts"
10393
+ },
10394
+ {
10395
+ "name": "SkeletonBones",
10396
+ "kind": "interface",
10397
+ "subpath": "./skeleton",
10398
+ "declaringModule": "skeleton/index.d.ts"
10399
+ },
10400
+ {
10401
+ "name": "createSceneControls",
10402
+ "kind": "function",
10403
+ "subpath": "./testing",
10404
+ "declaringModule": "testing/SceneControls.d.ts"
10405
+ },
10154
10406
  {
10155
10407
  "name": "fakeAudio",
10156
10408
  "kind": "function",
@@ -10199,6 +10451,18 @@
10199
10451
  "subpath": "./testing",
10200
10452
  "declaringModule": "testing/index.d.ts"
10201
10453
  },
10454
+ {
10455
+ "name": "SceneControls",
10456
+ "kind": "interface",
10457
+ "subpath": "./testing",
10458
+ "declaringModule": "testing/SceneControls.d.ts"
10459
+ },
10460
+ {
10461
+ "name": "SceneStep",
10462
+ "kind": "type",
10463
+ "subpath": "./testing",
10464
+ "declaringModule": "testing/SceneControls.d.ts"
10465
+ },
10202
10466
  {
10203
10467
  "name": "spawn",
10204
10468
  "kind": "function",
@@ -10445,6 +10709,12 @@
10445
10709
  "subpath": "./two-d",
10446
10710
  "declaringModule": "two-d/render/ImageModifiers.d.ts"
10447
10711
  },
10712
+ {
10713
+ "name": "ArticulatedChain",
10714
+ "kind": "class",
10715
+ "subpath": "./two-d",
10716
+ "declaringModule": "two-d/render/SkeletalSprite.d.ts"
10717
+ },
10448
10718
  {
10449
10719
  "name": "assertAutotileLayout",
10450
10720
  "kind": "function",
@@ -10625,6 +10895,18 @@
10625
10895
  "subpath": "./two-d",
10626
10896
  "declaringModule": "two-d/render/Camera.d.ts"
10627
10897
  },
10898
+ {
10899
+ "name": "ChainOptions",
10900
+ "kind": "interface",
10901
+ "subpath": "./two-d",
10902
+ "declaringModule": "two-d/render/SkeletalSprite.d.ts"
10903
+ },
10904
+ {
10905
+ "name": "ChainRig",
10906
+ "kind": "class",
10907
+ "subpath": "./two-d",
10908
+ "declaringModule": "two-d/render/SkeletalSprite.d.ts"
10909
+ },
10628
10910
  {
10629
10911
  "name": "channelScaleMatrix",
10630
10912
  "kind": "function",
@@ -12029,6 +12311,12 @@
12029
12311
  "subpath": "./two-d",
12030
12312
  "declaringModule": "two-d/stage/DialogueStage.d.ts"
12031
12313
  },
12314
+ {
12315
+ "name": "SkeletalSprite",
12316
+ "kind": "class",
12317
+ "subpath": "./two-d",
12318
+ "declaringModule": "two-d/render/SkeletalSprite.d.ts"
12319
+ },
12032
12320
  {
12033
12321
  "name": "Skin",
12034
12322
  "kind": "interface",
@@ -12791,6 +13079,12 @@
12791
13079
  "subpath": "./two-d/render",
12792
13080
  "declaringModule": "two-d/render/ImageModifiers.d.ts"
12793
13081
  },
13082
+ {
13083
+ "name": "ArticulatedChain",
13084
+ "kind": "class",
13085
+ "subpath": "./two-d/render",
13086
+ "declaringModule": "two-d/render/SkeletalSprite.d.ts"
13087
+ },
12794
13088
  {
12795
13089
  "name": "assertAutotileLayout",
12796
13090
  "kind": "function",
@@ -12911,6 +13205,18 @@
12911
13205
  "subpath": "./two-d/render",
12912
13206
  "declaringModule": "two-d/render/Camera.d.ts"
12913
13207
  },
13208
+ {
13209
+ "name": "ChainOptions",
13210
+ "kind": "interface",
13211
+ "subpath": "./two-d/render",
13212
+ "declaringModule": "two-d/render/SkeletalSprite.d.ts"
13213
+ },
13214
+ {
13215
+ "name": "ChainRig",
13216
+ "kind": "class",
13217
+ "subpath": "./two-d/render",
13218
+ "declaringModule": "two-d/render/SkeletalSprite.d.ts"
13219
+ },
12914
13220
  {
12915
13221
  "name": "channelScaleMatrix",
12916
13222
  "kind": "function",
@@ -13601,6 +13907,12 @@
13601
13907
  "subpath": "./two-d/render",
13602
13908
  "declaringModule": "two-d/render/Shape2D.d.ts"
13603
13909
  },
13910
+ {
13911
+ "name": "SkeletalSprite",
13912
+ "kind": "class",
13913
+ "subpath": "./two-d/render",
13914
+ "declaringModule": "two-d/render/SkeletalSprite.d.ts"
13915
+ },
13604
13916
  {
13605
13917
  "name": "snapZoom",
13606
13918
  "kind": "function",
@@ -15,6 +15,8 @@ export type { AssetProgress } from './paths.ts';
15
15
  export { load, texture, get, isLoaded, release } from './loader.ts';
16
16
  export type { LoadAssetsOptions } from './loader.ts';
17
17
  export { loadBinary, getBinary, isBinaryLoaded, releaseBinary } from './binary.ts';
18
+ export { sanitizeSvg, svgScaleVariants, svgDataUri, splitSvgGroups } from './svg.ts';
19
+ export type { ScaleVariant, SvgVariant } from './svg.ts';
18
20
  export type { LoadBinaryOptions } from './binary.ts';
19
21
  export { AssetStream } from './Streaming.ts';
20
22
  export type { AssetBundle, AssetStreamOptions } from './Streaming.ts';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/assets/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACnF,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACpE,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACnF,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/assets/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACnF,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACpE,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEnF,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AACrF,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACzD,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC"}
@@ -13,6 +13,7 @@
13
13
  export { setBase, setAssetMap, isCompiled, paths, has, resolve } from './paths.js';
14
14
  export { load, texture, get, isLoaded, release } from './loader.js';
15
15
  export { loadBinary, getBinary, isBinaryLoaded, releaseBinary } from './binary.js';
16
+ export { sanitizeSvg, svgScaleVariants, svgDataUri, splitSvgGroups } from './svg.js';
16
17
  export { AssetStream } from './Streaming.js';
17
18
  export { fetchWithByteProgress } from './ByteProgress.js';
18
19
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/assets/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAGnF,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGpE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGnF,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/assets/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAGnF,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGpE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEnF,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAIrF,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * SVG as inbound data (roadmap 398): sanitization, named scale variants, and group-split
3
+ * parts.
4
+ *
5
+ * An SVG is inbound data that can carry active content - `<script>`, event-handler
6
+ * attributes, `foreignObject` - the same way a save slot or a replay file is inbound data.
7
+ * `sanitizeSvg` refuses what it cannot prove inert, by name, conservatively: anything the
8
+ * scan does not recognize as inert is an error, never a silent pass, and the posture is the
9
+ * same one the saves and replay rules carry rather than a trust in the `file://` CSP to make
10
+ * the question moot.
11
+ *
12
+ * `svgScaleVariants` rasterizes one source once per named scale (1x, 2x, 3x), so a game
13
+ * picks the variant by device the way it picks an asset path, instead of every call site
14
+ * re-deciding a resolution multiplier. `splitSvgGroups` loads an SVG authored with named
15
+ * `<g>` groups as one standalone SVG per group - the natural authoring form for a skeletal
16
+ * puppet: one drawing, one source of truth, split at load.
17
+ *
18
+ * All three are string processing with no renderer: they run headless, and the compiled
19
+ * `data:` URI form is what they consume and produce.
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * import { sanitizeSvg, splitSvgGroups } from '@datamoc/mw_games/assets';
24
+ *
25
+ * const puppet = '<svg><g id=\"arm\"><rect/></g></svg>';
26
+ * const parts = splitSvgGroups(sanitizeSvg(puppet));
27
+ * console.log(Object.keys(parts)); // ['arm']
28
+ * ```
29
+ */
30
+ /**
31
+ * Refuse an SVG that is not proven inert, by name. The scan is deliberately conservative:
32
+ * it names what it refuses, and anything it cannot read as inert is an error rather than a
33
+ * silent pass. The source is returned unchanged once proven inert - sanitization here is a
34
+ * gate, not a rewrite; what a game authors is what a game gets.
35
+ */
36
+ export declare function sanitizeSvg(source: string): string;
37
+ export interface ScaleVariant {
38
+ /** the name a game picks the variant by, the way it picks an asset path */
39
+ name: string;
40
+ /** the rasterization resolution multiple, so a device picks its sharpness at load */
41
+ resolution: number;
42
+ }
43
+ export interface SvgVariant {
44
+ name: string;
45
+ /** a `data:image/svg\+xml` URI ready for the asset loader */
46
+ src: string;
47
+ /** the loader's own resolution hint, carried from the named scale */
48
+ resolution: number;
49
+ }
50
+ /**
51
+ * The `data:image/svg+xml` form of a source, ready for the loader.
52
+ *
53
+ * @example
54
+ * ```ts
55
+ * import { svgDataUri } from '@datamoc/mw_games/assets';
56
+ *
57
+ * console.log(svgDataUri('<svg/>').startsWith('data:image/svg+xml,')); // true
58
+ * ```
59
+ */
60
+ export declare function svgDataUri(source: string): string;
61
+ /**
62
+ * One source, one variant per named scale. Each variant is the same proven-inert source at
63
+ * its own resolution multiple, so the loader rasterizes each scale once and a game asks for
64
+ * the variant by name instead of re-deciding a multiplier at every call site.
65
+ */
66
+ /**
67
+ * One source, one variant per named scale.
68
+ *
69
+ * @example
70
+ * ```ts
71
+ * import { svgScaleVariants } from '@datamoc/mw_games/assets';
72
+ *
73
+ * const [sharp] = svgScaleVariants('<svg/>', [{ name: '3x', resolution: 3 }]);
74
+ * console.log(sharp.resolution); // 3
75
+ * ```
76
+ */
77
+ export declare function svgScaleVariants(source: string, scales: readonly ScaleVariant[]): SvgVariant[];
78
+ /**
79
+ * An SVG authored with named `<g id="...">` groups loads as one standalone SVG per group -
80
+ * the natural authoring form for a skeletal puppet: one drawing, one source of truth for
81
+ * palette and style, split at load. Each part keeps the original `<svg>` root attributes
82
+ * (viewBox included) and carries exactly one group's children.
83
+ *
84
+ * Refused by name: an empty id, a duplicate id, and any group the scan cannot balance.
85
+ */
86
+ export declare function splitSvgGroups(source: string): Record<string, string>;
87
+ //# sourceMappingURL=svg.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"svg.d.ts","sourceRoot":"","sources":["../../src/assets/svg.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAcH;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAIlD;AAED,MAAM,WAAW,YAAY;IAC5B,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb,qFAAqF;IACrF,UAAU,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,6DAA6D;IAC7D,GAAG,EAAE,MAAM,CAAC;IACZ,qEAAqE;IACrE,UAAU,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED;;;;GAIG;AACH;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,YAAY,EAAE,GAAG,UAAU,EAAE,CAa9F;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CA2CrE"}