@1agh/maude 0.15.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/LICENSE +21 -0
- package/README.md +166 -0
- package/cli/bin/maude.exe +15 -0
- package/cli/bin/maude.mjs +45 -0
- package/cli/bin/mdcc.exe +10 -0
- package/cli/bin/mdcc.mjs +7 -0
- package/cli/cli-wrapper.cjs +67 -0
- package/cli/commands/config.mjs +94 -0
- package/cli/commands/design.mjs +386 -0
- package/cli/commands/help.mjs +57 -0
- package/cli/commands/init.mjs +178 -0
- package/cli/commands/version.mjs +7 -0
- package/cli/install.cjs +113 -0
- package/cli/lib/argv.mjs +37 -0
- package/cli/lib/argv.test.mjs +46 -0
- package/cli/lib/copy-tree.mjs +78 -0
- package/package.json +94 -0
- package/plugins/design/dev-server/annotations-context-toolbar.tsx +397 -0
- package/plugins/design/dev-server/annotations-layer.tsx +1717 -0
- package/plugins/design/dev-server/api.ts +674 -0
- package/plugins/design/dev-server/bin/_screenshot-playwright.mjs +50 -0
- package/plugins/design/dev-server/bin/bootstrap-check.sh +83 -0
- package/plugins/design/dev-server/bin/canvas-edit.sh +48 -0
- package/plugins/design/dev-server/bin/handoff.sh +27 -0
- package/plugins/design/dev-server/bin/screenshot.sh +232 -0
- package/plugins/design/dev-server/bin/server-up.sh +135 -0
- package/plugins/design/dev-server/bin/slug.sh +22 -0
- package/plugins/design/dev-server/bin/smoke.sh +272 -0
- package/plugins/design/dev-server/build.ts +267 -0
- package/plugins/design/dev-server/canvas-build.ts +219 -0
- package/plugins/design/dev-server/canvas-edit.ts +388 -0
- package/plugins/design/dev-server/canvas-header.ts +165 -0
- package/plugins/design/dev-server/canvas-icons.tsx +131 -0
- package/plugins/design/dev-server/canvas-lib-inline.ts +260 -0
- package/plugins/design/dev-server/canvas-lib-resolver.ts +85 -0
- package/plugins/design/dev-server/canvas-lib.tsx +1995 -0
- package/plugins/design/dev-server/canvas-meta.schema.json +181 -0
- package/plugins/design/dev-server/canvas-pipeline.ts +270 -0
- package/plugins/design/dev-server/canvas-shell.tsx +813 -0
- package/plugins/design/dev-server/client/app.jsx +2027 -0
- package/plugins/design/dev-server/client/hmr.mjs +85 -0
- package/plugins/design/dev-server/client/iframe-lazy.mjs +121 -0
- package/plugins/design/dev-server/client/index.html +15 -0
- package/plugins/design/dev-server/client/styles/0-reset.css +18 -0
- package/plugins/design/dev-server/client/styles/1-tokens.css +297 -0
- package/plugins/design/dev-server/client/styles/2-layout.css +35 -0
- package/plugins/design/dev-server/client/styles/3-shell.css +906 -0
- package/plugins/design/dev-server/client/styles/4-components.css +1268 -0
- package/plugins/design/dev-server/client/styles/5-utilities.css +4 -0
- package/plugins/design/dev-server/client/styles/_index.css +24 -0
- package/plugins/design/dev-server/client/styles.css +1419 -0
- package/plugins/design/dev-server/config.schema.json +147 -0
- package/plugins/design/dev-server/context-menu.tsx +343 -0
- package/plugins/design/dev-server/context.ts +173 -0
- package/plugins/design/dev-server/dist/client.bundle.js +20323 -0
- package/plugins/design/dev-server/dist/styles.css +2875 -0
- package/plugins/design/dev-server/examples/README.md +9 -0
- package/plugins/design/dev-server/examples/perf-100-artboards.tsx +113 -0
- package/plugins/design/dev-server/fs-watch.ts +63 -0
- package/plugins/design/dev-server/handoff.ts +721 -0
- package/plugins/design/dev-server/history.ts +125 -0
- package/plugins/design/dev-server/hmr-broadcast.ts +114 -0
- package/plugins/design/dev-server/http.ts +413 -0
- package/plugins/design/dev-server/input-router.tsx +485 -0
- package/plugins/design/dev-server/inspect.ts +365 -0
- package/plugins/design/dev-server/locator.ts +159 -0
- package/plugins/design/dev-server/mem.ts +97 -0
- package/plugins/design/dev-server/runtime-bundle.ts +235 -0
- package/plugins/design/dev-server/server.mjs +1246 -0
- package/plugins/design/dev-server/server.ts +131 -0
- package/plugins/design/dev-server/test/_helpers.ts +81 -0
- package/plugins/design/dev-server/test/active-state.test.ts +145 -0
- package/plugins/design/dev-server/test/annotations-api.test.ts +146 -0
- package/plugins/design/dev-server/test/annotations-layer.test.ts +419 -0
- package/plugins/design/dev-server/test/binary-smoke.test.ts +47 -0
- package/plugins/design/dev-server/test/bundle-smoke.test.ts +29 -0
- package/plugins/design/dev-server/test/canvas-build.test.ts +78 -0
- package/plugins/design/dev-server/test/canvas-edit.test.ts +139 -0
- package/plugins/design/dev-server/test/canvas-header.test.ts +127 -0
- package/plugins/design/dev-server/test/canvas-lib-inline.test.ts +146 -0
- package/plugins/design/dev-server/test/canvas-lib-resolver.test.ts +112 -0
- package/plugins/design/dev-server/test/canvas-meta-api.test.ts +236 -0
- package/plugins/design/dev-server/test/canvas-pipeline.test.ts +180 -0
- package/plugins/design/dev-server/test/canvas-route.test.ts +176 -0
- package/plugins/design/dev-server/test/fs-watch.test.ts +41 -0
- package/plugins/design/dev-server/test/handoff-static-frames.test.ts +215 -0
- package/plugins/design/dev-server/test/handoff.test.ts +281 -0
- package/plugins/design/dev-server/test/history-rollback.test.ts +62 -0
- package/plugins/design/dev-server/test/hmr-broadcast.test.ts +108 -0
- package/plugins/design/dev-server/test/input-router.test.ts +316 -0
- package/plugins/design/dev-server/test/locator.test.ts +214 -0
- package/plugins/design/dev-server/test/perf-harness.ts +193 -0
- package/plugins/design/dev-server/test/phase-3.6-smoke.test.ts +77 -0
- package/plugins/design/dev-server/test/runtime-bundle.test.ts +69 -0
- package/plugins/design/dev-server/test/server-lifecycle.test.ts +28 -0
- package/plugins/design/dev-server/test/tool-palette.test.tsx +55 -0
- package/plugins/design/dev-server/test/use-annotation-selection.test.tsx +77 -0
- package/plugins/design/dev-server/test/use-artboard-drag.test.ts +325 -0
- package/plugins/design/dev-server/test/use-selection-set.test.tsx +166 -0
- package/plugins/design/dev-server/test/use-snap-guides.test.ts +190 -0
- package/plugins/design/dev-server/test/use-tool-mode.test.tsx +93 -0
- package/plugins/design/dev-server/test/ws-handshake.test.ts +33 -0
- package/plugins/design/dev-server/tool-palette.tsx +278 -0
- package/plugins/design/dev-server/tsconfig.json +26 -0
- package/plugins/design/dev-server/use-annotation-selection.tsx +92 -0
- package/plugins/design/dev-server/use-annotations-visibility.tsx +43 -0
- package/plugins/design/dev-server/use-artboard-drag.tsx +445 -0
- package/plugins/design/dev-server/use-selection-set.tsx +224 -0
- package/plugins/design/dev-server/use-snap-guides.tsx +215 -0
- package/plugins/design/dev-server/use-tool-mode.tsx +114 -0
- package/plugins/design/dev-server/ws.ts +90 -0
- package/plugins/design/templates/_shell.html +177 -0
- package/plugins/design/templates/canvas.tsx.template +54 -0
- package/plugins/design/templates/design-system-inspiration/_MAPPING.md +277 -0
- package/plugins/design/templates/design-system-inspiration/_README.md +71 -0
- package/plugins/design/templates/design-system-inspiration/audience-consumer/components-banner.html +68 -0
- package/plugins/design/templates/design-system-inspiration/audience-consumer/components-empty-state-generous.html +39 -0
- package/plugins/design/templates/design-system-inspiration/audience-consumer/components-feature-grid.html +62 -0
- package/plugins/design/templates/design-system-inspiration/audience-consumer/components-marketing-card.html +63 -0
- package/plugins/design/templates/design-system-inspiration/audience-consumer/components-testimonial.html +80 -0
- package/plugins/design/templates/design-system-inspiration/audience-developer/components-code-block.html +71 -0
- package/plugins/design/templates/design-system-inspiration/audience-developer/components-diff-view.html +65 -0
- package/plugins/design/templates/design-system-inspiration/audience-developer/components-log-stream.html +62 -0
- package/plugins/design/templates/design-system-inspiration/audience-developer/components-monospace-table.html +57 -0
- package/plugins/design/templates/design-system-inspiration/audience-developer/components-terminal-pane.html +67 -0
- package/plugins/design/templates/design-system-inspiration/audience-developer/type-mono.html +57 -0
- package/plugins/design/templates/design-system-inspiration/audience-pro/colors-presence.html +74 -0
- package/plugins/design/templates/design-system-inspiration/audience-pro/components-command-palette.html +90 -0
- package/plugins/design/templates/design-system-inspiration/audience-pro/components-keyboard.html +51 -0
- package/plugins/design/templates/design-system-inspiration/audience-pro/components-list.html +89 -0
- package/plugins/design/templates/design-system-inspiration/audience-pro/components-shortcuts-overlay.html +85 -0
- package/plugins/design/templates/design-system-inspiration/audience-pro/components-toast-menu.html +80 -0
- package/plugins/design/templates/design-system-inspiration/core/INDEX.md.tpl +25 -0
- package/plugins/design/templates/design-system-inspiration/core/README.orchestration.md.tpl +71 -0
- package/plugins/design/templates/design-system-inspiration/core/README.philosophy.md.tpl +77 -0
- package/plugins/design/templates/design-system-inspiration/core/SKILL.md.tpl +50 -0
- package/plugins/design/templates/design-system-inspiration/core/colors_and_type.css.tpl +111 -0
- package/plugins/design/templates/design-system-inspiration/core/config.json.tpl +28 -0
- package/plugins/design/templates/design-system-inspiration/core/preview/_layout.css +113 -0
- package/plugins/design/templates/design-system-inspiration/core/preview/colors-accent.html +48 -0
- package/plugins/design/templates/design-system-inspiration/core/preview/colors-surfaces.html +49 -0
- package/plugins/design/templates/design-system-inspiration/core/preview/colors-text.html +52 -0
- package/plugins/design/templates/design-system-inspiration/core/preview/components-buttons.html +83 -0
- package/plugins/design/templates/design-system-inspiration/core/preview/components-cards.html +79 -0
- package/plugins/design/templates/design-system-inspiration/core/preview/components-inputs.html +82 -0
- package/plugins/design/templates/design-system-inspiration/core/preview/motion.html +66 -0
- package/plugins/design/templates/design-system-inspiration/core/preview/spacing-scale.html +53 -0
- package/plugins/design/templates/design-system-inspiration/core/preview/type-scale.html +62 -0
- package/plugins/design/templates/design-system-inspiration/foundations/borders.html +39 -0
- package/plugins/design/templates/design-system-inspiration/foundations/elevation.html +46 -0
- package/plugins/design/templates/design-system-inspiration/foundations/focus.html +48 -0
- package/plugins/design/templates/design-system-inspiration/foundations/grid.html +51 -0
- package/plugins/design/templates/design-system-inspiration/foundations/iconography.html +73 -0
- package/plugins/design/templates/design-system-inspiration/foundations/opacity.html +45 -0
- package/plugins/design/templates/design-system-inspiration/foundations/radii.html +40 -0
- package/plugins/design/templates/design-system-inspiration/foundations/selection.html +45 -0
- package/plugins/design/templates/design-system-inspiration/meta/accessibility.html +62 -0
- package/plugins/design/templates/design-system-inspiration/meta/i18n.html +73 -0
- package/plugins/design/templates/design-system-inspiration/meta/presence-multiplayer.html +71 -0
- package/plugins/design/templates/design-system-inspiration/meta/tokens-index.html +80 -0
- package/plugins/design/templates/design-system-inspiration/patterns/patterns-auth.html +78 -0
- package/plugins/design/templates/design-system-inspiration/patterns/patterns-data-density.html +61 -0
- package/plugins/design/templates/design-system-inspiration/patterns/patterns-error-pages.html +70 -0
- package/plugins/design/templates/design-system-inspiration/patterns/patterns-form-layouts.html +70 -0
- package/plugins/design/templates/design-system-inspiration/patterns/patterns-onboarding.html +71 -0
- package/plugins/design/templates/design-system-inspiration/patterns/patterns-pricing.html +83 -0
- package/plugins/design/templates/design-system-inspiration/platform-desktop/components-resize-panels.html +63 -0
- package/plugins/design/templates/design-system-inspiration/platform-desktop/ui_kits-desktop-index.html +55 -0
- package/plugins/design/templates/design-system-inspiration/platform-desktop/ui_kits-desktop-showcase.html +302 -0
- package/plugins/design/templates/design-system-inspiration/platform-mobile/components-bottom-sheet.html +63 -0
- package/plugins/design/templates/design-system-inspiration/platform-mobile/components-pull-to-refresh.html +74 -0
- package/plugins/design/templates/design-system-inspiration/platform-mobile/components-segmented-control.html +51 -0
- package/plugins/design/templates/design-system-inspiration/platform-mobile/components-tab-bar.html +57 -0
- package/plugins/design/templates/design-system-inspiration/platform-mobile/ui_kits-mobile-index.html +58 -0
- package/plugins/design/templates/design-system-inspiration/platform-mobile/ui_kits-mobile-showcase.html +237 -0
- package/plugins/design/templates/design-system-inspiration/status/colors-status.html +49 -0
- package/plugins/design/templates/design-system-inspiration/status/components-status.html +63 -0
- package/plugins/design/templates/design-system-inspiration/status/skeletons.html +74 -0
- package/plugins/design/templates/design-system-inspiration/theme-both/colors-themes-side-by-side.html +59 -0
- package/plugins/design/templates/design-system-inspiration/universal/components-callout.html +74 -0
- package/plugins/design/templates/design-system-inspiration/universal/components-dialogs.html +81 -0
- package/plugins/design/templates/design-system-inspiration/universal/components-tables.html +101 -0
- package/plugins/design/templates/design-system-inspiration/universal/components-toggles.html +74 -0
- package/plugins/design/templates/design-system-inspiration/universal/components-tooltips.html +74 -0
- package/plugins/design/templates/design-system-inspiration/universal/empty-state.html.tpl +34 -0
- package/plugins/design/templates/design-system-inspiration/universal/logo.html +42 -0
- package/plugins/design/templates/ds-specimen.tsx.template +59 -0
- package/plugins/flow/.claude-plugin/config.schema.json +398 -0
- package/plugins/flow/README.md +45 -0
- package/plugins/flow/templates/ai-skeleton/INDEX.md +50 -0
- package/plugins/flow/templates/ai-skeleton/README.md +46 -0
- package/plugins/flow/templates/ai-skeleton/browser/har/.gitkeep +0 -0
- package/plugins/flow/templates/ai-skeleton/browser/snapshots/.gitkeep +0 -0
- package/plugins/flow/templates/ai-skeleton/business/README.md +12 -0
- package/plugins/flow/templates/ai-skeleton/context/README.md +12 -0
- package/plugins/flow/templates/ai-skeleton/decisions/README.md +20 -0
- package/plugins/flow/templates/ai-skeleton/design-import/.gitkeep +0 -0
- package/plugins/flow/templates/ai-skeleton/dev-logs/.gitkeep +0 -0
- package/plugins/flow/templates/ai-skeleton/device/.gitkeep +0 -0
- package/plugins/flow/templates/ai-skeleton/docs/README.md +5 -0
- package/plugins/flow/templates/ai-skeleton/logs/.gitkeep +0 -0
- package/plugins/flow/templates/ai-skeleton/logs/README.md +13 -0
- package/plugins/flow/templates/ai-skeleton/plans/README.md +16 -0
- package/plugins/flow/templates/ai-skeleton/plans/archive/.gitkeep +0 -0
- package/plugins/flow/templates/ai-skeleton/release-guide.md +35 -0
- package/plugins/flow/templates/ai-skeleton/reviews/README.md +15 -0
- package/plugins/flow/templates/ai-skeleton/scenarios/README.md +26 -0
- package/plugins/flow/templates/ai-skeleton/scenarios/_lib/.gitkeep +0 -0
- package/plugins/flow/templates/ai-skeleton/state/STATE.md +25 -0
- package/plugins/flow/templates/ai-skeleton/templates/HANDOFF.md +32 -0
- package/plugins/flow/templates/ai-skeleton/workflows.config.json +74 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# dev-server/examples/
|
|
2
|
+
|
|
3
|
+
Fixtures used by dev-server perf + smoke tests. Not user content — for actual
|
|
4
|
+
canvas surfaces refer to a project's `.design/ui/` directory and the DS
|
|
5
|
+
specimens under `.design/system/<ds>/preview/`.
|
|
6
|
+
|
|
7
|
+
Files here ship with the dev-server install and serve as reference workloads
|
|
8
|
+
for engine perf measurements (e.g. driver selection, hover recompute, viewport
|
|
9
|
+
HMR cycles).
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @canvas Perf Lab — 100 DCArtboards × 30 nodes (Phase 4 T6)
|
|
3
|
+
* @ds project
|
|
4
|
+
* @platform web-desktop
|
|
5
|
+
* @opt_out full
|
|
6
|
+
* @brief Throwaway canvas for measuring pan/zoom FPS at scale. 100
|
|
7
|
+
* DCArtboards arranged on the default 3-col grid, each holding
|
|
8
|
+
* 30 inert DOM nodes. No real CSS bling — solid background,
|
|
9
|
+
* hairline border, monospace label, that's it. The point is
|
|
10
|
+
* to stress the world-transform path, not to look pretty.
|
|
11
|
+
*
|
|
12
|
+
* Usage:
|
|
13
|
+
* 1. Open in the dev-server, fit-to-screen (Cmd+0).
|
|
14
|
+
* 2. Hold space and drag for 5 s; record FPS via window
|
|
15
|
+
* `__perf__.fps()` (instrumentation below) or via Chrome
|
|
16
|
+
* DevTools Performance panel.
|
|
17
|
+
* 3. Zoom around the cursor with wheel for 5 s; record FPS.
|
|
18
|
+
* 4. Compare against the Phase 3.4 perf budget targets.
|
|
19
|
+
*
|
|
20
|
+
* Results land in .ai/decisions/DDR-024 + .ai/logs/phase-4-perf-<date>.md.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import { useEffect } from 'react';
|
|
24
|
+
|
|
25
|
+
import { DCArtboard, DCSection, DesignCanvas } from '@maude/canvas-lib';
|
|
26
|
+
|
|
27
|
+
const ARTBOARD_COUNT = 100;
|
|
28
|
+
const NODES_PER_ARTBOARD = 30;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Tiny RAF-FPS sampler exposed on `window.__perf__` so the harness (or a
|
|
32
|
+
* human at the DevTools console) can grab a 1 s rolling average without
|
|
33
|
+
* installing anything. Idempotent — no-op on the second mount.
|
|
34
|
+
*/
|
|
35
|
+
function installFpsSampler(): void {
|
|
36
|
+
if (typeof window === 'undefined') return;
|
|
37
|
+
const w = window as unknown as { __perf__?: { fps: () => number } };
|
|
38
|
+
if (w.__perf__) return;
|
|
39
|
+
let last = performance.now();
|
|
40
|
+
const samples: number[] = [];
|
|
41
|
+
const SAMPLE_WINDOW = 60; // ~1 s at 60 fps
|
|
42
|
+
function tick(now: number) {
|
|
43
|
+
const dt = now - last;
|
|
44
|
+
last = now;
|
|
45
|
+
if (dt > 0) {
|
|
46
|
+
samples.push(1000 / dt);
|
|
47
|
+
if (samples.length > SAMPLE_WINDOW) samples.shift();
|
|
48
|
+
}
|
|
49
|
+
requestAnimationFrame(tick);
|
|
50
|
+
}
|
|
51
|
+
requestAnimationFrame(tick);
|
|
52
|
+
w.__perf__ = {
|
|
53
|
+
fps: () => {
|
|
54
|
+
if (samples.length === 0) return 0;
|
|
55
|
+
const sum = samples.reduce((a, b) => a + b, 0);
|
|
56
|
+
return Math.round((sum / samples.length) * 10) / 10;
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function PerfArtboardBody({ index }: { index: number }) {
|
|
62
|
+
const nodes = Array.from({ length: NODES_PER_ARTBOARD }, (_, i) => i);
|
|
63
|
+
return (
|
|
64
|
+
<div
|
|
65
|
+
style={{
|
|
66
|
+
padding: 16,
|
|
67
|
+
display: 'grid',
|
|
68
|
+
gridTemplateColumns: 'repeat(5, 1fr)',
|
|
69
|
+
gap: 8,
|
|
70
|
+
fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace',
|
|
71
|
+
fontSize: 11,
|
|
72
|
+
color: '#444',
|
|
73
|
+
}}
|
|
74
|
+
>
|
|
75
|
+
{nodes.map((n) => (
|
|
76
|
+
<div
|
|
77
|
+
key={n}
|
|
78
|
+
style={{
|
|
79
|
+
padding: 8,
|
|
80
|
+
border: '1px solid rgba(0,0,0,0.12)',
|
|
81
|
+
borderRadius: 3,
|
|
82
|
+
background: index % 2 === 0 ? '#fff' : '#fafafa',
|
|
83
|
+
minHeight: 48,
|
|
84
|
+
}}
|
|
85
|
+
>
|
|
86
|
+
AB{index.toString().padStart(3, '0')}·N{n.toString().padStart(2, '0')}
|
|
87
|
+
</div>
|
|
88
|
+
))}
|
|
89
|
+
</div>
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export default function Perf100Artboards() {
|
|
94
|
+
useEffect(() => {
|
|
95
|
+
installFpsSampler();
|
|
96
|
+
}, []);
|
|
97
|
+
const ids = Array.from({ length: ARTBOARD_COUNT }, (_, i) => i);
|
|
98
|
+
return (
|
|
99
|
+
<DesignCanvas>
|
|
100
|
+
<DCSection id="perf-lab" title="Perf — 100 × 30">
|
|
101
|
+
{ids.map((i) => {
|
|
102
|
+
const id = `ab-${i.toString().padStart(3, '0')}`;
|
|
103
|
+
const label = `AB-${i.toString().padStart(3, '0')} · ${NODES_PER_ARTBOARD}n`;
|
|
104
|
+
return (
|
|
105
|
+
<DCArtboard key={id} id={id} label={label} width={1280} height={820}>
|
|
106
|
+
<PerfArtboardBody index={i} />
|
|
107
|
+
</DCArtboard>
|
|
108
|
+
);
|
|
109
|
+
})}
|
|
110
|
+
</DCSection>
|
|
111
|
+
</DesignCanvas>
|
|
112
|
+
);
|
|
113
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// Recursive filesystem watcher.
|
|
2
|
+
// Bun ships a working recursive fs.watch on macOS/Linux/Windows out of the box;
|
|
3
|
+
// no @parcel/watcher needed. We debounce per-path so a single editor save (which
|
|
4
|
+
// often emits ~3 events on macOS) collapses to one bus notification.
|
|
5
|
+
|
|
6
|
+
import { watch } from 'node:fs';
|
|
7
|
+
import path from 'node:path';
|
|
8
|
+
|
|
9
|
+
import type { Context } from './context.ts';
|
|
10
|
+
|
|
11
|
+
export interface FsWatch {
|
|
12
|
+
start(): void;
|
|
13
|
+
stop(): void;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const DEBOUNCE_MS = 50;
|
|
17
|
+
|
|
18
|
+
export function createFsWatch(ctx: Context): FsWatch {
|
|
19
|
+
let watcher: ReturnType<typeof watch> | null = null;
|
|
20
|
+
const seen = new Map<string, number>();
|
|
21
|
+
|
|
22
|
+
function emit(filename: string) {
|
|
23
|
+
const now = Date.now();
|
|
24
|
+
const prev = seen.get(filename) ?? 0;
|
|
25
|
+
if (now - prev < DEBOUNCE_MS) return;
|
|
26
|
+
seen.set(filename, now);
|
|
27
|
+
const ext = path.extname(filename).toLowerCase();
|
|
28
|
+
const rel = filename.replace(/\\/g, '/');
|
|
29
|
+
if (ext === '.html') ctx.bus.emit('fs:html', rel);
|
|
30
|
+
else if (ext === '.css') ctx.bus.emit('fs:css', rel);
|
|
31
|
+
else if (ext === '.json') ctx.bus.emit('fs:json', rel);
|
|
32
|
+
ctx.bus.emit('fs:any', rel);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function start() {
|
|
36
|
+
if (watcher) return;
|
|
37
|
+
try {
|
|
38
|
+
watcher = watch(ctx.paths.designRoot, { recursive: true }, (_event, filename) => {
|
|
39
|
+
if (!filename) return;
|
|
40
|
+
// Skip our own runtime artifacts.
|
|
41
|
+
if (filename.startsWith('_server.json')) return;
|
|
42
|
+
if (filename.startsWith('_active.json')) return;
|
|
43
|
+
if (filename.startsWith(`_history${path.sep}`) || filename.startsWith('_history/')) return;
|
|
44
|
+
emit(filename);
|
|
45
|
+
});
|
|
46
|
+
} catch (err) {
|
|
47
|
+
console.warn('[fs-watch] failed to start:', err instanceof Error ? err.message : err);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function stop() {
|
|
52
|
+
if (!watcher) return;
|
|
53
|
+
try {
|
|
54
|
+
watcher.close();
|
|
55
|
+
} catch {
|
|
56
|
+
/* ignore */
|
|
57
|
+
}
|
|
58
|
+
watcher = null;
|
|
59
|
+
seen.clear();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return { start, stop };
|
|
63
|
+
}
|