ice-web-components 1.2.0 → 1.4.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 +98 -4
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/types/components/ICELabel.d.ts +8 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/model/ICEBiosModel.d.ts +124 -0
- package/dist/types/model/ICEDosModel.d.ts +84 -0
- package/dist/types/model/ICEMazeModel.d.ts +78 -0
- package/dist/types/model/ICESortModel.d.ts +63 -0
- package/dist/types/model/ICETracePlayerModel.d.ts +53 -0
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -27,11 +27,12 @@ rings and shadows) is drawn by the engine.
|
|
|
27
27
|
- **Bootstrap 5 token theme** (plus a dark theme) — swap with one call.
|
|
28
28
|
- **No name collisions with the engine** — the package’s runtime exports are
|
|
29
29
|
disjoint from `ice-render`’s (there is a regression test for it).
|
|
30
|
-
- **Actually tested** —
|
|
30
|
+
- **Actually tested** — 825 unit tests (107 suites: form validation, overlay
|
|
31
31
|
positioning, keyboard navigation, sort/hover/focus edge cases, the Minesweeper,
|
|
32
32
|
Tetris, Snake, 2048 and CHIP-8 rule/machine models, the pixel canvas and the undo
|
|
33
|
-
stack
|
|
34
|
-
`qa:
|
|
33
|
+
stack, the console BIOS, the trace player + sorting/pathfinding and the DOS terminal)
|
|
34
|
+
plus eight browser QA suites (`qa:admin`, `qa:gallery`, `qa:workbench`, `qa:xp`,
|
|
35
|
+
`qa:arcade`, `qa:pixel`, `qa:algo`, `qa:dos` — 277 assertions) that drive the demo pages with
|
|
35
36
|
real mouse and keyboard events and fail on any console error.
|
|
36
37
|
|
|
37
38
|
## Quick start
|
|
@@ -220,6 +221,26 @@ the buttons and the sound switch are all ICE components, and there is not a sing
|
|
|
220
221
|
bitmap asset in the picture. Four cartridges are plugged in, and the cartridge row at
|
|
221
222
|
the top switches between them (a fifth slot, Chinese chess, is disabled for now).
|
|
222
223
|
|
|
224
|
+
Before any cartridge runs, the console boots through its own **BIOS**: a power-on
|
|
225
|
+
self-test (CPU / RAM / VRAM / SOUND / CART, each line going grey → amber → green with a
|
|
226
|
+
beep) followed by a classic boot menu, exactly like the real thing.
|
|
227
|
+
|
|
228
|
+
| POST (power-on self-test) | BIOS boot menu |
|
|
229
|
+
|---|---|
|
|
230
|
+
|  |  |
|
|
231
|
+
|
|
232
|
+
`ICEBiosModel` is the state machine behind it (pure logic, 17 unit tests): the self-test
|
|
233
|
+
is a **timed sequence** the page advances with `tick(dt)` — each step owns its duration and
|
|
234
|
+
reports `pending` / `running` / `ok`; the menu is a cursor + confirm console UI with a
|
|
235
|
+
**wrapping** cursor; `confirm()` returns an *action* (`boot` / `settings` / `menu`) instead
|
|
236
|
+
of executing it, so the whole flow is testable in node. Settings (quick boot + default
|
|
237
|
+
cartridge) persist through an injected storage that degrades gracefully on corrupt JSON
|
|
238
|
+
or a full quota.
|
|
239
|
+
|
|
240
|
+
F2 (or the BIOS button) returns to the menu at any time — on a game page that *is* the
|
|
241
|
+
reset button. Any key during POST skips the rest of the self-test, and with quick boot on
|
|
242
|
+
(the factory default) the console goes straight back to the last cartridge after POST.
|
|
243
|
+
|
|
223
244
|
| | |
|
|
224
245
|
|---|---|
|
|
225
246
|
|  |  |
|
|
@@ -354,6 +375,71 @@ The three decisions worth stealing:
|
|
|
354
375
|
> proper `setSize(rows, cols, cellSize?)` that updates the internals, the state and the
|
|
355
376
|
> default width/height in one go, and clears the old cell data.
|
|
356
377
|
|
|
378
|
+
### `algorithm-sandbox.html` — ICE Algorithm Sandbox
|
|
379
|
+
|
|
380
|
+
Sorting and pathfinding, visualised as **recorded traces**: each algorithm runs to
|
|
381
|
+
completion up front and produces a list of frames; the page then plays them back with
|
|
382
|
+
play / pause / single-step / rewind / speed control.
|
|
383
|
+
|
|
384
|
+
| Sorting (`quick sort`, mid-run) | Pathfinding (`A*`) |
|
|
385
|
+
|---|---|
|
|
386
|
+
|  |  |
|
|
387
|
+
|
|
388
|
+
```ts
|
|
389
|
+
import { ICESortModel, ICEMazeModel, ICETracePlayerModel } from 'ice-web-components';
|
|
390
|
+
|
|
391
|
+
const sort = new ICESortModel({ size: 24, max: 32 });
|
|
392
|
+
const frames = sort.run('quick'); // 一帧 = 当前数组 + 正在比较/交换的下标 + 已就位的位置
|
|
393
|
+
const player = new ICETracePlayerModel({ speed: 8 });
|
|
394
|
+
player.load(frames); // 回放:play / pause / stepForward / seek / setSpeed / tick(dt)
|
|
395
|
+
|
|
396
|
+
const maze = new ICEMazeModel({ rows: 16, cols: 24 });
|
|
397
|
+
maze.randomWalls(0.24);
|
|
398
|
+
maze.solve('astar'); // 同样是一串帧:访问过的格子 / 边界 / 最终路径
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
Why “record a trace first, play it back later” instead of painting while the algorithm
|
|
402
|
+
runs: the algorithm becomes a plain function with a testable output (is the last frame
|
|
403
|
+
sorted? does every frame contain the same multiset? do BFS and A* agree on the shortest
|
|
404
|
+
path?), and the player gives pause/step/rewind for free. Four algorithms are covered on
|
|
405
|
+
each side — bubble / insertion / selection / merge / quick, and BFS / DFS / Dijkstra / A* —
|
|
406
|
+
with `ICETracePlayerModel` owning the clock (1–60 steps per second, auto-stop at the end).
|
|
407
|
+
|
|
408
|
+
Both visualisations are single `ICETileMap` nodes: the sorting bars are a `max × n` grid
|
|
409
|
+
where each column is filled from the bottom (blue = untouched, amber = comparing, red =
|
|
410
|
+
swapping, green = settled), and the maze is a grid of cell states. The A* comparison in
|
|
411
|
+
the QA is the honest one: same shortest path as BFS, **fewer cells visited** (the tie-break
|
|
412
|
+
among equal `f` values is what makes A* actually faster on an open grid).
|
|
413
|
+
|
|
414
|
+
### `dos-terminal.html` — ICE-DOS Terminal
|
|
415
|
+
|
|
416
|
+
A terminal you can actually type into: a virtual filesystem plus 16 commands, all in a
|
|
417
|
+
pure model (`ICEDosModel`) that never touches the DOM.
|
|
418
|
+
|
|
419
|
+

|
|
420
|
+
|
|
421
|
+
```ts
|
|
422
|
+
import { ICEDosModel } from 'ice-web-components';
|
|
423
|
+
|
|
424
|
+
const dos = new ICEDosModel();
|
|
425
|
+
dos.run('cd games'); // 路径解析:\ / .. . 与大小写不敏感
|
|
426
|
+
dos.run('dir'); // { lines: [{ text, type: 'output' | 'error' }], effect? }
|
|
427
|
+
dos.run('echo hi > note.txt'); // 重定向(> 覆盖 / >> 追加)
|
|
428
|
+
dos.complete('type TET'); // Tab 补全 → 'type TETRIS.EXE'
|
|
429
|
+
dos.historyPrev(); // ↑ 历史
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
`run()` never throws — a typo becomes one `error` line, so the terminal cannot be crashed
|
|
433
|
+
by typing. The page owns the three things a terminal needs on top of that: echoing the
|
|
434
|
+
command line, auto-scrolling to the bottom, and a blinking cursor that **simulates** a
|
|
435
|
+
keyboard buffer (TAB is completion, ↑↓ is history, `Ctrl+L` clears, `exit` shows a
|
|
436
|
+
“powered off” overlay, any key boots again).
|
|
437
|
+
|
|
438
|
+
> This page deliberately does **not** start `ICEFocusManager` (same call as the arcade
|
|
439
|
+
> page): the focus manager treats TAB as “rotate focus”, which steals the terminal’s
|
|
440
|
+
> completion key — and once focus lands on the window’s “重新开机” button, pressing Enter
|
|
441
|
+
> to run a command reboots the machine instead.
|
|
442
|
+
|
|
357
443
|
## Components
|
|
358
444
|
|
|
359
445
|
| Group | Components |
|
|
@@ -365,7 +451,7 @@ The three decisions worth stealing:
|
|
|
365
451
|
| Feedback & status | `ICEAlert` `ICEModal` `ICEDrawer` `ICEMessage` `ICENotification` `ICETooltip` `ICEPopover` `ICEPopconfirm` `ICETour` `ICEFloatButton` `ICEEmpty` `ICESkeleton` `ICESpin` `ICEResult` `ICESteps` `ICEOverlayManager` |
|
|
366
452
|
| Navigation | `ICEMenu` `ICEBreadcrumb` `ICEAnchor` `ICEBackTop` `ICEDropdown` `ICEPagination` `ICETabs` |
|
|
367
453
|
| Layout & core | `ICEWidget` `ICEContainer` `ICEHoverManager` `ICEFocusManager` `ICEMessageManager` `ICEManager` (`ICEPainter` / `ICELayoutManager` are types) |
|
|
368
|
-
| Models | `ICEButtonModel` `ICEToggleModel` `ICEBoundedRangeModel` `ICESelectionModel` `ICEFormModel` `ICEHistoryModel` `ICEPixelModel` `ICETetrisModel` `ICESnakeModel` `ICE2048Model` `ICEChip8Model` `ICEMinesweeperModel` `ICEHighScoreModel` |
|
|
454
|
+
| Models | `ICEButtonModel` `ICEToggleModel` `ICEBoundedRangeModel` `ICESelectionModel` `ICEFormModel` `ICEBiosModel` `ICEHistoryModel` `ICEPixelModel` `ICETracePlayerModel` `ICESortModel` `ICEMazeModel` `ICEDosModel` `ICETetrisModel` `ICESnakeModel` `ICE2048Model` `ICEChip8Model` `ICEMinesweeperModel` `ICEHighScoreModel` |
|
|
369
455
|
|
|
370
456
|
Helper functions: `attachTooltip` `attachPopover` `attachPopconfirm` `attachDropdown`
|
|
371
457
|
`openModal` `openDrawer` `getICEOverlayManager` `getICEFocusManager` `getICEMessageManager`
|
|
@@ -510,6 +596,14 @@ npm run qa:arcade
|
|
|
510
596
|
# PNG (IHDR-checked) / SVG exports
|
|
511
597
|
npm run qa:pixel
|
|
512
598
|
|
|
599
|
+
# browser QA for examples/algorithm-sandbox.html: playback (play/pause/step/space),
|
|
600
|
+
# switching algorithms, the A*-vs-BFS comparison, and painting walls with a real drag
|
|
601
|
+
npm run qa:algo
|
|
602
|
+
|
|
603
|
+
# browser QA for examples/dos-terminal.html: typing commands, TAB completion, history,
|
|
604
|
+
# redirection, Ctrl+L, exit/reboot and auto-scroll
|
|
605
|
+
npm run qa:dos
|
|
606
|
+
|
|
513
607
|
# docs: regenerate the API reference and check relative links
|
|
514
608
|
npm run docs
|
|
515
609
|
```
|