@madojs/mado 0.11.1 → 0.13.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/AGENTS.md +116 -32
- package/CHANGELOG.md +216 -1
- package/README.md +158 -173
- package/dist/src/component.d.ts +6 -3
- package/dist/src/component.d.ts.map +1 -0
- package/dist/src/component.js +163 -36
- package/dist/src/component.js.map +1 -1
- package/dist/src/context.d.ts +13 -32
- package/dist/src/context.d.ts.map +1 -0
- package/dist/src/context.js +73 -48
- package/dist/src/context.js.map +1 -1
- package/dist/src/css.d.ts +1 -0
- package/dist/src/css.d.ts.map +1 -0
- package/dist/src/css.js +34 -5
- package/dist/src/css.js.map +1 -1
- package/dist/src/devtools-hook.d.ts +14 -0
- package/dist/src/devtools-hook.d.ts.map +1 -0
- package/dist/src/devtools-hook.js +27 -0
- package/dist/src/devtools-hook.js.map +1 -0
- package/dist/src/devtools.d.ts +24 -22
- package/dist/src/devtools.d.ts.map +1 -0
- package/dist/src/devtools.js +230 -58
- package/dist/src/devtools.js.map +1 -1
- package/dist/src/diagnostics.d.ts +12 -0
- package/dist/src/diagnostics.d.ts.map +1 -0
- package/dist/src/diagnostics.js +68 -8
- package/dist/src/diagnostics.js.map +1 -1
- package/dist/src/each.d.ts +1 -5
- package/dist/src/each.d.ts.map +1 -0
- package/dist/src/each.js +0 -8
- package/dist/src/each.js.map +1 -1
- package/dist/src/forms.d.ts +27 -96
- package/dist/src/forms.d.ts.map +1 -0
- package/dist/src/forms.js +184 -394
- package/dist/src/forms.js.map +1 -1
- package/dist/src/head.d.ts +7 -6
- package/dist/src/head.d.ts.map +1 -0
- package/dist/src/head.js +8 -7
- package/dist/src/head.js.map +1 -1
- package/dist/src/html/bindings.d.ts +1 -0
- package/dist/src/html/bindings.d.ts.map +1 -0
- package/dist/src/html/bindings.js.map +1 -1
- package/dist/src/html/parser.d.ts +4 -5
- package/dist/src/html/parser.d.ts.map +1 -0
- package/dist/src/html/parser.js +64 -15
- package/dist/src/html/parser.js.map +1 -1
- package/dist/src/html/template-types.d.ts +1 -0
- package/dist/src/html/template-types.d.ts.map +1 -0
- package/dist/src/html/template-types.js.map +1 -1
- package/dist/src/html/template.d.ts +5 -1
- package/dist/src/html/template.d.ts.map +1 -0
- package/dist/src/html/template.js +102 -13
- package/dist/src/html/template.js.map +1 -1
- package/dist/src/index.d.ts +15 -12
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +18 -10
- package/dist/src/index.js.map +1 -1
- package/dist/src/json.d.ts +3 -0
- package/dist/src/json.d.ts.map +1 -0
- package/dist/src/json.js +14 -0
- package/dist/src/json.js.map +1 -0
- package/dist/src/lifecycle.d.ts +1 -0
- package/dist/src/lifecycle.d.ts.map +1 -0
- package/dist/src/lifecycle.js +3 -2
- package/dist/src/lifecycle.js.map +1 -1
- package/dist/src/page.d.ts +63 -28
- package/dist/src/page.d.ts.map +1 -0
- package/dist/src/page.js +5 -0
- package/dist/src/page.js.map +1 -1
- package/dist/src/persisted.d.ts +6 -1
- package/dist/src/persisted.d.ts.map +1 -0
- package/dist/src/persisted.js +17 -11
- package/dist/src/persisted.js.map +1 -1
- package/dist/src/resource.d.ts +2 -1
- package/dist/src/resource.d.ts.map +1 -0
- package/dist/src/resource.js +128 -50
- package/dist/src/resource.js.map +1 -1
- package/dist/src/router/base.d.ts +66 -0
- package/dist/src/router/base.d.ts.map +1 -0
- package/dist/src/router/base.js +168 -0
- package/dist/src/router/base.js.map +1 -0
- package/dist/src/router/manifest.d.ts +1 -0
- package/dist/src/router/manifest.d.ts.map +1 -0
- package/dist/src/router/manifest.js +156 -171
- package/dist/src/router/manifest.js.map +1 -1
- package/dist/src/router/match.d.ts +17 -2
- package/dist/src/router/match.d.ts.map +1 -0
- package/dist/src/router/match.js +60 -6
- package/dist/src/router/match.js.map +1 -1
- package/dist/src/router/navigation.d.ts +1 -0
- package/dist/src/router/navigation.d.ts.map +1 -0
- package/dist/src/router/navigation.js +58 -9
- package/dist/src/router/navigation.js.map +1 -1
- package/dist/src/signal.d.ts +1 -0
- package/dist/src/signal.d.ts.map +1 -0
- package/dist/src/signal.js +46 -17
- package/dist/src/signal.js.map +1 -1
- package/dist/src/static-runtime.d.ts +82 -0
- package/dist/src/static-runtime.d.ts.map +1 -0
- package/dist/src/static-runtime.js +209 -0
- package/dist/src/static-runtime.js.map +1 -0
- package/dist/src/vite/index.d.ts +32 -3
- package/dist/src/vite/index.d.ts.map +1 -0
- package/dist/src/vite/index.js +49 -17
- package/dist/src/vite/index.js.map +1 -1
- package/docs/README.md +5 -8
- package/docs/architecture/adr/0001-browser-static-snapshots.md +132 -0
- package/docs/architecture/v1-roadmap.md +19 -0
- package/docs/en/00-the-mado-way.md +1 -1
- package/docs/en/01-quickstart.md +183 -0
- package/docs/en/10-pages-and-components.md +279 -0
- package/docs/en/11-templates-and-signals.md +211 -0
- package/docs/en/12-routing.md +229 -0
- package/docs/en/13-data.md +227 -0
- package/docs/en/14-forms.md +91 -0
- package/docs/en/15-static-snapshots.md +181 -0
- package/docs/en/{10-app-architecture.md → 16-app-architecture.md} +56 -4
- package/docs/en/{13-deployment.md → 20-deployment.md} +79 -17
- package/docs/en/{15-error-handling.md → 21-error-handling.md} +9 -6
- package/docs/en/{14-testing.md → 22-testing.md} +6 -5
- package/docs/en/23-cookbook.md +292 -0
- package/docs/en/24-devtools-and-diagnostics.md +45 -0
- package/docs/en/{18-api-freeze-map.md → 30-api-freeze-map.md} +17 -9
- package/docs/en/{20-v1-stability.md → 32-v1-stability.md} +5 -5
- package/docs/en/33-migration-0.12-0.13.md +56 -0
- package/docs/en/40-llm-guide.md +774 -0
- package/docs/en/{06-for-backenders.md → 41-for-backenders.md} +28 -25
- package/docs/en/{05-why-mado.md → 42-why-mado.md} +3 -3
- package/docs/en/README.md +99 -27
- package/docs/recipes/nginx/Containerfile +26 -0
- package/docs/recipes/nginx/nginx.conf +42 -0
- package/llms.txt +263 -210
- package/package.json +51 -23
- package/scripts/clean.mjs +8 -0
- package/scripts/cli/generate.mjs +57 -10
- package/scripts/cli/help.mjs +13 -5
- package/scripts/cli/index.mjs +31 -7
- package/scripts/cli/init.mjs +19 -19
- package/scripts/cli/release.mjs +38 -83
- package/scripts/cli/run.mjs +5 -3
- package/scripts/logger.mjs +117 -0
- package/scripts/output-guard.mjs +128 -0
- package/scripts/preview.mjs +105 -24
- package/scripts/static/browser.mjs +695 -0
- package/scripts/static/discover.mjs +284 -0
- package/scripts/static/output.mjs +141 -0
- package/scripts/static/serialize.mjs +212 -0
- package/scripts/static/server.mjs +167 -0
- package/scripts/static.mjs +205 -0
- package/starters/default/README.md +57 -55
- package/starters/default/package.json +6 -12
- package/starters/default/src/app.routes.ts +20 -33
- package/starters/default/src/components/feature-card.component.ts +40 -0
- package/starters/default/src/components/live-counter.component.ts +57 -0
- package/starters/default/src/content/guides.ts +55 -0
- package/starters/default/src/main.ts +9 -13
- package/starters/default/src/pages/app.page.ts +41 -0
- package/starters/default/src/pages/guide.page.ts +40 -0
- package/starters/default/src/pages/home.page.ts +49 -0
- package/starters/default/src/pages/not-found.page.ts +18 -0
- package/starters/default/src/styles/document.css +39 -0
- package/starters/default/src/styles/reset.css +37 -0
- package/starters/default/src/styles/tokens.css +30 -0
- package/starters/default/src/styles.d.ts +3 -1
- package/starters/default/src/vite-env.d.ts +1 -1
- package/starters/default/tsconfig.node.json +13 -0
- package/starters/default/vite.config.ts +14 -4
- package/starters/modular/README.md +142 -0
- package/starters/modular/index.html +13 -0
- package/starters/modular/package.json +30 -0
- package/starters/modular/src/app.routes.ts +39 -0
- package/starters/{default → modular}/src/layouts/app-shell.layout.ts +9 -7
- package/starters/{default → modular}/src/layouts/auth-shell.layout.ts +3 -3
- package/starters/modular/src/main.ts +16 -0
- package/starters/{default → modular}/src/modules/auth/login.page.ts +5 -12
- package/starters/{default → modular}/src/modules/billing/pages/invoice-detail.page.ts +3 -4
- package/starters/{default → modular}/src/modules/billing/pages/invoices-list.page.ts +4 -4
- package/starters/{default → modular}/src/modules/home/home.page.ts +5 -7
- package/starters/modular/src/modules/home/not-found.page.ts +14 -0
- package/starters/{default → modular}/src/shared/styles/reset.css +21 -1
- package/starters/modular/src/styles.d.ts +1 -0
- package/starters/modular/src/vite-env.d.ts +1 -0
- package/starters/modular/tsconfig.json +33 -0
- package/starters/modular/tsconfig.node.json +13 -0
- package/starters/modular/vite.config.ts +132 -0
- package/TODO.md +0 -79
- package/dist/src/lazy.d.ts +0 -38
- package/dist/src/lazy.js +0 -73
- package/dist/src/lazy.js.map +0 -1
- package/docs/en/01-routing.md +0 -152
- package/docs/en/02-project-layout.md +0 -124
- package/docs/en/03-static-bake.md +0 -249
- package/docs/en/04-ide-setup.md +0 -162
- package/docs/en/07-llm-pitfalls.md +0 -724
- package/docs/en/08-llm-zero-history-test.md +0 -56
- package/docs/en/09-shadow-vs-light-dom.md +0 -174
- package/docs/en/11-layouts.md +0 -113
- package/docs/en/12-auth-and-api.md +0 -124
- package/docs/en/16-bake-cookbook.md +0 -100
- package/docs/en/17-shadow-dom-forms.md +0 -192
- package/docs/fr/00-the-mado-way.md +0 -85
- package/docs/fr/01-routing.md +0 -120
- package/docs/fr/02-project-layout.md +0 -84
- package/docs/fr/03-static-bake.md +0 -289
- package/docs/fr/04-ide-setup.md +0 -162
- package/docs/fr/05-why-mado.md +0 -193
- package/docs/fr/06-for-backenders.md +0 -438
- package/docs/fr/07-llm-pitfalls.md +0 -625
- package/docs/fr/08-llm-zero-history-test.md +0 -38
- package/docs/fr/09-shadow-vs-light-dom.md +0 -65
- package/docs/fr/10-app-architecture.md +0 -138
- package/docs/fr/11-layouts.md +0 -47
- package/docs/fr/12-auth-and-api.md +0 -76
- package/docs/fr/13-deployment.md +0 -57
- package/docs/fr/14-testing.md +0 -41
- package/docs/fr/15-error-handling.md +0 -50
- package/docs/fr/16-bake-cookbook.md +0 -88
- package/docs/fr/17-shadow-dom-forms.md +0 -196
- package/docs/fr/18-api-freeze-map.md +0 -63
- package/docs/fr/19-reactivity-ordering.md +0 -97
- package/docs/fr/20-v1-stability.md +0 -88
- package/docs/fr/README.md +0 -27
- package/docs/ru/00-the-mado-way.md +0 -84
- package/docs/ru/01-routing.md +0 -119
- package/docs/ru/02-project-layout.md +0 -84
- package/docs/ru/03-static-bake.md +0 -250
- package/docs/ru/04-ide-setup.md +0 -144
- package/docs/ru/05-why-mado.md +0 -193
- package/docs/ru/06-for-backenders.md +0 -428
- package/docs/ru/07-llm-pitfalls.md +0 -624
- package/docs/ru/08-llm-zero-history-test.md +0 -57
- package/docs/ru/09-shadow-vs-light-dom.md +0 -63
- package/docs/ru/10-app-architecture.md +0 -152
- package/docs/ru/11-layouts.md +0 -47
- package/docs/ru/12-auth-and-api.md +0 -75
- package/docs/ru/13-deployment.md +0 -66
- package/docs/ru/14-testing.md +0 -50
- package/docs/ru/15-error-handling.md +0 -56
- package/docs/ru/16-bake-cookbook.md +0 -95
- package/docs/ru/17-shadow-dom-forms.md +0 -193
- package/docs/ru/18-api-freeze-map.md +0 -64
- package/docs/ru/19-reactivity-ordering.md +0 -95
- package/docs/ru/20-v1-stability.md +0 -82
- package/docs/ru/README.md +0 -25
- package/docs/uk/00-the-mado-way.md +0 -82
- package/docs/uk/01-routing.md +0 -76
- package/docs/uk/02-project-layout.md +0 -73
- package/docs/uk/03-static-bake.md +0 -48
- package/docs/uk/04-ide-setup.md +0 -26
- package/docs/uk/05-why-mado.md +0 -34
- package/docs/uk/06-for-backenders.md +0 -55
- package/docs/uk/07-llm-pitfalls.md +0 -145
- package/docs/uk/08-llm-zero-history-test.md +0 -34
- package/docs/uk/09-shadow-vs-light-dom.md +0 -58
- package/docs/uk/10-app-architecture.md +0 -97
- package/docs/uk/11-layouts.md +0 -47
- package/docs/uk/12-auth-and-api.md +0 -70
- package/docs/uk/13-deployment.md +0 -40
- package/docs/uk/14-testing.md +0 -34
- package/docs/uk/15-error-handling.md +0 -32
- package/docs/uk/16-bake-cookbook.md +0 -36
- package/docs/uk/17-shadow-dom-forms.md +0 -193
- package/docs/uk/18-api-freeze-map.md +0 -61
- package/docs/uk/19-reactivity-ordering.md +0 -95
- package/docs/uk/20-v1-stability.md +0 -83
- package/docs/uk/README.md +0 -27
- package/scripts/bake.mjs +0 -570
- package/scripts/package-smoke.mjs +0 -77
- package/scripts/release-notes.mjs +0 -66
- package/scripts/size-budget.mjs +0 -91
- package/starters/default/src/modules/home/not-found.page.ts +0 -11
- package/starters/default/src/shared/ui/x-button.component.ts +0 -49
- /package/docs/en/{19-reactivity-ordering.md → 31-reactivity-ordering.md} +0 -0
- /package/starters/{default → modular}/.editorconfig +0 -0
- /package/starters/{default → modular}/eslint.config.mjs +0 -0
- /package/starters/{default → modular}/public/favicon.svg +0 -0
- /package/starters/{default → modular}/src/modules/auth/_contracts/auth-api.types.ts +0 -0
- /package/starters/{default → modular}/src/modules/auth/auth.connector.ts +0 -0
- /package/starters/{default → modular}/src/modules/auth/auth.guard.ts +0 -0
- /package/starters/{default → modular}/src/modules/auth/auth.public.ts +0 -0
- /package/starters/{default → modular}/src/modules/auth/auth.routes.ts +0 -0
- /package/starters/{default → modular}/src/modules/auth/auth.service.ts +0 -0
- /package/starters/{default → modular}/src/modules/auth/auth.types.ts +0 -0
- /package/starters/{default → modular}/src/modules/billing/_contracts/stripe.types.ts +0 -0
- /package/starters/{default → modular}/src/modules/billing/api/stripe.connector.ts +0 -0
- /package/starters/{default → modular}/src/modules/billing/billing.public.ts +0 -0
- /package/starters/{default → modular}/src/modules/billing/billing.routes.ts +0 -0
- /package/starters/{default → modular}/src/modules/billing/billing.types.ts +0 -0
- /package/starters/{default → modular}/src/modules/billing/components/invoice-status-badge.component.ts +0 -0
- /package/starters/{default → modular}/src/modules/billing/data/invoices.resource.ts +0 -0
- /package/starters/{default → modular}/src/shared/http/http-client.ts +0 -0
- /package/starters/{default → modular}/src/shared/http/http-error.ts +0 -0
- /package/starters/{default → modular}/src/shared/http/interceptors.ts +0 -0
- /package/starters/{default → modular}/src/shared/lib/format-date.ts +0 -0
- /package/starters/{default → modular}/src/shared/styles/content.css +0 -0
- /package/starters/{default → modular}/src/shared/styles/shell.css +0 -0
- /package/starters/{default → modular}/src/shared/styles/tokens.css +0 -0
- /package/starters/{default → modular}/src/shared/ui/x-spinner.component.ts +0 -0
|
@@ -4,9 +4,10 @@
|
|
|
4
4
|
* There is NO window/document/history or signals here — only functions
|
|
5
5
|
* over strings and objects. This allows:
|
|
6
6
|
* - testing routing in Node without jsdom;
|
|
7
|
-
* - reusing the same compile/regex in
|
|
7
|
+
* - reusing the same compile/regex in static discovery / prefetch without duplication.
|
|
8
8
|
*/
|
|
9
|
-
import { type Guard, type Page, type RouteEntry } from "../page.js";
|
|
9
|
+
import { isPage, type Guard, type Page, type RouteEntry } from "../page.js";
|
|
10
|
+
export { isPage };
|
|
10
11
|
import type { TemplateResult } from "../html/template-types.js";
|
|
11
12
|
export type RouteParams = Record<string, string>;
|
|
12
13
|
export type RouteHandler = (params: RouteParams) => TemplateResult;
|
|
@@ -35,6 +36,19 @@ export declare function matchRoute(path: string, compiled: readonly CompiledRout
|
|
|
35
36
|
} | null;
|
|
36
37
|
/** Simple regex WITHOUT keys — for prefetch (we only need the match fact). */
|
|
37
38
|
export declare function patternToRegex(pattern: string): RegExp;
|
|
39
|
+
/**
|
|
40
|
+
* Extract `:key` names from a route pattern, in declaration order.
|
|
41
|
+
* Used by static discovery and prefetch URL synthesis; centralised here so
|
|
42
|
+
* the two pipelines stay in sync.
|
|
43
|
+
*/
|
|
44
|
+
export declare function paramKeys(pattern: string): string[];
|
|
45
|
+
/**
|
|
46
|
+
* Materialise a route pattern into a concrete pathname by substituting
|
|
47
|
+
* declared `:key` placeholders with URL-encoded values from `params`.
|
|
48
|
+
* Throws with route context when a required param is missing or the
|
|
49
|
+
* resulting URL contains query / fragment.
|
|
50
|
+
*/
|
|
51
|
+
export declare function applyParams(pattern: string, params: Record<string, string>): string;
|
|
38
52
|
export type RoutesMap = Record<string, RouteEntry>;
|
|
39
53
|
export interface FlatEntry {
|
|
40
54
|
loader: () => Promise<Page> | Page;
|
|
@@ -65,3 +79,4 @@ export declare function joinPath(a: string, b: string): string;
|
|
|
65
79
|
* the rest of the code works only with the unified loader.
|
|
66
80
|
*/
|
|
67
81
|
export declare function normalize(entry: RouteEntry): () => Promise<Page> | Page;
|
|
82
|
+
//# sourceMappingURL=match.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"match.d.ts","sourceRoot":"","sources":["../../../src/router/match.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAEL,MAAM,EACN,KAAK,KAAK,EACV,KAAK,IAAI,EACT,KAAK,UAAU,EAChB,MAAM,YAAY,CAAC;AAIpB,OAAO,EAAE,MAAM,EAAE,CAAC;AAClB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAEhE,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACjD,MAAM,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,WAAW,KAAK,cAAc,CAAC;AACnE,MAAM,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;AAElD,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,OAAO,EAAE,YAAY,CAAC;CACvB;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,aAAa,CAY7E;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,SAAS,aAAa,EAAE,GACjC;IAAE,KAAK,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,WAAW,CAAA;CAAE,GAAG,IAAI,CAatD;AAED,8EAA8E;AAC9E,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAGtD;AAqBD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAOnD;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7B,MAAM,CAkBR;AAKD,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;AAEnD,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACnC,OAAO,EAAE,KAAK,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;IAC3C;;;OAGG;IACH,MAAM,EAAE,KAAK,EAAE,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CACrB,GAAG,EAAE,SAAS,EACd,MAAM,SAAK,EACX,OAAO,GAAE,SAAS,CAAC,SAAS,CAAM,EAClC,MAAM,GAAE,KAAK,EAAO,GACnB,KAAK,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAsB5B;AAMD,8DAA8D;AAC9D,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAMrD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAevE"}
|
package/dist/src/router/match.js
CHANGED
|
@@ -4,9 +4,12 @@
|
|
|
4
4
|
* There is NO window/document/history or signals here — only functions
|
|
5
5
|
* over strings and objects. This allows:
|
|
6
6
|
* - testing routing in Node without jsdom;
|
|
7
|
-
* - reusing the same compile/regex in
|
|
7
|
+
* - reusing the same compile/regex in static discovery / prefetch without duplication.
|
|
8
8
|
*/
|
|
9
9
|
import { isLayoutGroup, isPage, } from "../page.js";
|
|
10
|
+
// Re-export isPage so build-time tooling (scripts/static/discover.mjs)
|
|
11
|
+
// can pull every routing helper it needs from a single module.
|
|
12
|
+
export { isPage };
|
|
10
13
|
/**
|
|
11
14
|
* Compile a pattern like `/users/:id` into a `CompiledRoute` with
|
|
12
15
|
* named keys and a regex for matching against `location.pathname`.
|
|
@@ -18,10 +21,7 @@ export function compile(pattern, handler) {
|
|
|
18
21
|
return { pattern, regex: /.*/, keys: [], handler };
|
|
19
22
|
}
|
|
20
23
|
const keys = [];
|
|
21
|
-
const re = pattern
|
|
22
|
-
keys.push(m.slice(1));
|
|
23
|
-
return "([^/]+)";
|
|
24
|
-
});
|
|
24
|
+
const re = routePatternSource(pattern, keys);
|
|
25
25
|
return {
|
|
26
26
|
pattern,
|
|
27
27
|
regex: new RegExp(`^${re}/?$`),
|
|
@@ -51,9 +51,63 @@ export function matchRoute(path, compiled) {
|
|
|
51
51
|
}
|
|
52
52
|
/** Simple regex WITHOUT keys — for prefetch (we only need the match fact). */
|
|
53
53
|
export function patternToRegex(pattern) {
|
|
54
|
-
const re = pattern
|
|
54
|
+
const re = routePatternSource(pattern);
|
|
55
55
|
return new RegExp(`^${re}/?$`);
|
|
56
56
|
}
|
|
57
|
+
function routePatternSource(pattern, keys) {
|
|
58
|
+
const input = pattern.replace(/\/$/, "");
|
|
59
|
+
let source = "";
|
|
60
|
+
let cursor = 0;
|
|
61
|
+
const params = /:([\w]+)/g;
|
|
62
|
+
for (const match of input.matchAll(params)) {
|
|
63
|
+
const index = match.index ?? 0;
|
|
64
|
+
source += escapeRegex(input.slice(cursor, index));
|
|
65
|
+
source += "([^/]+)";
|
|
66
|
+
keys?.push(match[1]);
|
|
67
|
+
cursor = index + match[0].length;
|
|
68
|
+
}
|
|
69
|
+
return source + escapeRegex(input.slice(cursor));
|
|
70
|
+
}
|
|
71
|
+
function escapeRegex(value) {
|
|
72
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Extract `:key` names from a route pattern, in declaration order.
|
|
76
|
+
* Used by static discovery and prefetch URL synthesis; centralised here so
|
|
77
|
+
* the two pipelines stay in sync.
|
|
78
|
+
*/
|
|
79
|
+
export function paramKeys(pattern) {
|
|
80
|
+
const keys = [];
|
|
81
|
+
pattern.replace(/:([\w]+)/g, (_m, key) => {
|
|
82
|
+
keys.push(key);
|
|
83
|
+
return "";
|
|
84
|
+
});
|
|
85
|
+
return keys;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Materialise a route pattern into a concrete pathname by substituting
|
|
89
|
+
* declared `:key` placeholders with URL-encoded values from `params`.
|
|
90
|
+
* Throws with route context when a required param is missing or the
|
|
91
|
+
* resulting URL contains query / fragment.
|
|
92
|
+
*/
|
|
93
|
+
export function applyParams(pattern, params) {
|
|
94
|
+
if (pattern === "/")
|
|
95
|
+
return "/";
|
|
96
|
+
const pathname = pattern.replace(/:([\w]+)/g, (_m, key) => {
|
|
97
|
+
const value = params[key];
|
|
98
|
+
if (value == null) {
|
|
99
|
+
throw new Error(`[mado] missing param :${key} for ${pattern}`);
|
|
100
|
+
}
|
|
101
|
+
return encodeURIComponent(String(value));
|
|
102
|
+
});
|
|
103
|
+
if (pathname.includes("?") || pathname.includes("#")) {
|
|
104
|
+
throw new Error(`[mado] ${pattern}: query strings and fragments are not part of a route pathname.`);
|
|
105
|
+
}
|
|
106
|
+
const absolute = pathname.startsWith("/") ? pathname : `/${pathname}`;
|
|
107
|
+
return absolute.length > 1 && absolute.endsWith("/")
|
|
108
|
+
? absolute.slice(0, -1)
|
|
109
|
+
: absolute;
|
|
110
|
+
}
|
|
57
111
|
/**
|
|
58
112
|
* Unfold a layout-group manifest into a flat list of `[fullPattern, FlatEntry]`.
|
|
59
113
|
* Accumulates parent layouts along the way, so each leaf route
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"match.js","sourceRoot":"","sources":["../../../src/router/match.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"match.js","sourceRoot":"","sources":["../../../src/router/match.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Pure pattern matching + flatten/normalize of the manifest.\n *\n * There is NO window/document/history or signals here — only functions\n * over strings and objects. This allows:\n * - testing routing in Node without jsdom;\n * - reusing the same compile/regex in static discovery / prefetch without duplication.\n */\n\nimport {\n isLayoutGroup,\n isPage,\n type Guard,\n type Page,\n type RouteEntry,\n} from \"../page.js\";\n\n// Re-export isPage so build-time tooling (scripts/static/discover.mjs)\n// can pull every routing helper it needs from a single module.\nexport { isPage };\nimport type { TemplateResult } from \"../html/template-types.js\";\n\nexport type RouteParams = Record<string, string>;\nexport type RouteHandler = (params: RouteParams) => TemplateResult;\nexport type Routes = Record<string, RouteHandler>;\n\nexport interface CompiledRoute {\n pattern: string;\n regex: RegExp;\n keys: string[];\n handler: RouteHandler;\n}\n\n/**\n * Compile a pattern like `/users/:id` into a `CompiledRoute` with\n * named keys and a regex for matching against `location.pathname`.\n *\n * Special case `*` — wildcard fallback, matches anything.\n */\nexport function compile(pattern: string, handler: RouteHandler): CompiledRoute {\n if (pattern === \"*\") {\n return { pattern, regex: /.*/, keys: [], handler };\n }\n const keys: string[] = [];\n const re = routePatternSource(pattern, keys);\n return {\n pattern,\n regex: new RegExp(`^${re}/?$`),\n keys,\n handler,\n };\n}\n\n/**\n * Find the first matching CompiledRoute for path. Returns already\n * decoded params (decodeURIComponent on each segment).\n * Wildcard (`*`) is skipped — handle it separately as a fallback.\n */\nexport function matchRoute(\n path: string,\n compiled: readonly CompiledRoute[],\n): { route: CompiledRoute; params: RouteParams } | null {\n for (const r of compiled) {\n if (r.pattern === \"*\") continue;\n const m = r.regex.exec(path);\n if (m) {\n const params: RouteParams = {};\n r.keys.forEach((k, i) => {\n params[k] = decodeURIComponent(m[i + 1] ?? \"\");\n });\n return { route: r, params };\n }\n }\n return null;\n}\n\n/** Simple regex WITHOUT keys — for prefetch (we only need the match fact). */\nexport function patternToRegex(pattern: string): RegExp {\n const re = routePatternSource(pattern);\n return new RegExp(`^${re}/?$`);\n}\n\nfunction routePatternSource(pattern: string, keys?: string[]): string {\n const input = pattern.replace(/\\/$/, \"\");\n let source = \"\";\n let cursor = 0;\n const params = /:([\\w]+)/g;\n for (const match of input.matchAll(params)) {\n const index = match.index ?? 0;\n source += escapeRegex(input.slice(cursor, index));\n source += \"([^/]+)\";\n keys?.push(match[1]!);\n cursor = index + match[0].length;\n }\n return source + escapeRegex(input.slice(cursor));\n}\n\nfunction escapeRegex(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * Extract `:key` names from a route pattern, in declaration order.\n * Used by static discovery and prefetch URL synthesis; centralised here so\n * the two pipelines stay in sync.\n */\nexport function paramKeys(pattern: string): string[] {\n const keys: string[] = [];\n pattern.replace(/:([\\w]+)/g, (_m, key) => {\n keys.push(key);\n return \"\";\n });\n return keys;\n}\n\n/**\n * Materialise a route pattern into a concrete pathname by substituting\n * declared `:key` placeholders with URL-encoded values from `params`.\n * Throws with route context when a required param is missing or the\n * resulting URL contains query / fragment.\n */\nexport function applyParams(\n pattern: string,\n params: Record<string, string>,\n): string {\n if (pattern === \"/\") return \"/\";\n const pathname = pattern.replace(/:([\\w]+)/g, (_m, key) => {\n const value = params[key];\n if (value == null) {\n throw new Error(`[mado] missing param :${key} for ${pattern}`);\n }\n return encodeURIComponent(String(value));\n });\n if (pathname.includes(\"?\") || pathname.includes(\"#\")) {\n throw new Error(\n `[mado] ${pattern}: query strings and fragments are not part of a route pathname.`,\n );\n }\n const absolute = pathname.startsWith(\"/\") ? pathname : `/${pathname}`;\n return absolute.length > 1 && absolute.endsWith(\"/\")\n ? absolute.slice(0, -1)\n : absolute;\n}\n\n// ---------- Manifest (routes()) ----------\n\n\nexport type RoutesMap = Record<string, RouteEntry>;\n\nexport interface FlatEntry {\n loader: () => Promise<Page> | Page;\n layouts: Array<() => Promise<Page> | Page>;\n /**\n * Guards inherited from enclosing layout groups, outer → inner.\n * The page may add its own via `Page.guard` — those run last.\n */\n guards: Guard[];\n}\n\n/**\n * Unfold a layout-group manifest into a flat list of `[fullPattern, FlatEntry]`.\n * Accumulates parent layouts along the way, so each leaf route\n * \"knows\" all its layouts (from outer to inner).\n */\nexport function flatten(\n map: RoutesMap,\n prefix = \"\",\n layouts: FlatEntry[\"layouts\"] = [],\n guards: Guard[] = [],\n): Array<[string, FlatEntry]> {\n const out: Array<[string, FlatEntry]> = [];\n for (const [k, v] of Object.entries(map)) {\n const full = joinPath(prefix, k);\n if (isLayoutGroup(v)) {\n const nextLayouts = v.layout\n ? [...layouts, normalize(v.layout)]\n : layouts;\n const nextGuards = v.guard\n ? [...guards, ...toGuardArray(v.guard)]\n : guards;\n for (const sub of flatten(v.routes, full, nextLayouts, nextGuards)) {\n out.push(sub);\n }\n } else {\n out.push([\n full || \"/\",\n { loader: normalize(v), layouts, guards: [...guards] },\n ]);\n }\n }\n return out;\n}\n\nfunction toGuardArray(g: Guard | Guard[]): Guard[] {\n return Array.isArray(g) ? g : [g];\n}\n\n/** Careful path segment joining without duplicate slashes. */\nexport function joinPath(a: string, b: string): string {\n if (!a) return b;\n if (!b) return a;\n if (a.endsWith(\"/\")) a = a.slice(0, -1);\n if (b.startsWith(\"/\")) b = b.slice(1);\n return `${a}/${b}`;\n}\n\n/**\n * Normalise a RouteEntry into a uniform `() => Promise<Page> | Page`.\n *\n * RouteEntry comes in three forms:\n * - a ready Page → return as-is\n * - dynamic import → await the default export and check it's a Page\n * - something else → throw (bad manifest entry)\n *\n * This function is the single place that handles both forms;\n * the rest of the code works only with the unified loader.\n */\nexport function normalize(entry: RouteEntry): () => Promise<Page> | Page {\n if (isPage(entry)) return () => entry;\n if (typeof entry === \"function\") {\n return async () => {\n const mod = await (entry as () => Promise<{ default: Page }>)();\n const p = mod.default;\n if (!isPage(p)) {\n throw new Error(\n \"[mado] Lazy route did not return page({...}) as the default export.\",\n );\n }\n return p;\n };\n }\n throw new Error(\"[mado] Invalid entry in routes(): \" + String(entry));\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../../../src/router/navigation.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAU,KAAK,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAErD,OAAO,EAKL,KAAK,MAAM,EACZ,MAAM,YAAY,CAAC;AAEpB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAIhE,MAAM,WAAW,SAAS;IACxB,+DAA+D;IAC/D,IAAI,EAAE,MAAM,cAAc,CAAC;IAC3B,gCAAgC;IAChC,IAAI,EAAE,MAAM,MAAM,CAAC;IACnB,+BAA+B;IAC/B,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IACzD,kDAAkD;IAClD,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,MAAM,CACpB,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,aAAkB,GAC1B,SAAS,CAqKX;AA4BD;;;;;;;;;;;;GAYG;AACH,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAWvE;AAsJD,MAAM,WAAW,UAAU;IACzB,IAAI,MAAM,CAAC;IACX,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;CAC5D;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,SAAK,GAAG,UAAU,CAgBtE;AAED;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC"}
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import { signal } from "./../signal.js";
|
|
9
9
|
import { html } from "../html/template.js";
|
|
10
10
|
import { compile, matchRoute, } from "./match.js";
|
|
11
|
+
import { appBase, stripBase, withBase } from "./base.js";
|
|
11
12
|
/**
|
|
12
13
|
* Minimal History API router.
|
|
13
14
|
*
|
|
@@ -30,7 +31,10 @@ export function router(routes, options = {}) {
|
|
|
30
31
|
const useFocusManagement = options.focusManagement !== false;
|
|
31
32
|
const compiled = Object.entries(routes).map(([p, h]) => compile(p, h));
|
|
32
33
|
const fallback = compiled.find((r) => r.pattern === "*") ?? defaultFallback();
|
|
33
|
-
|
|
34
|
+
// Route pathname = browser pathname with the active Vite base stripped.
|
|
35
|
+
// The route matcher, route signal and any `path()` consumer always see
|
|
36
|
+
// base-free paths; `withBase()` re-adds it when we touch history.
|
|
37
|
+
const path = signal(stripBase(location.pathname));
|
|
34
38
|
const cleanups = [];
|
|
35
39
|
const scrollPositions = new Map();
|
|
36
40
|
let currentScrollKey = locationKey();
|
|
@@ -55,7 +59,7 @@ export function router(routes, options = {}) {
|
|
|
55
59
|
if (useScrollRestoration)
|
|
56
60
|
saveScroll(scrollPositions, currentScrollKey);
|
|
57
61
|
currentScrollKey = locationKey();
|
|
58
|
-
path.set(location.pathname);
|
|
62
|
+
path.set(stripBase(location.pathname));
|
|
59
63
|
if (useScrollRestoration)
|
|
60
64
|
restoreScroll(scrollPositions, currentScrollKey);
|
|
61
65
|
if (useFocusManagement)
|
|
@@ -87,8 +91,16 @@ export function router(routes, options = {}) {
|
|
|
87
91
|
const url = new URL(a.href, location.href);
|
|
88
92
|
if (url.origin !== location.origin)
|
|
89
93
|
return;
|
|
94
|
+
// Foreign-base links escape SPA navigation entirely so the browser
|
|
95
|
+
// performs a real document load (avoids matching "/other/..." against
|
|
96
|
+
// routes registered under base "/mado/").
|
|
97
|
+
const b = appBase;
|
|
98
|
+
if (b !== "/" && !(url.pathname === b.slice(0, -1) || url.pathname.startsWith(b))) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
90
101
|
e.preventDefault();
|
|
91
|
-
|
|
102
|
+
const routePath = stripBase(url.pathname);
|
|
103
|
+
api.navigate(routePath + url.search + url.hash);
|
|
92
104
|
};
|
|
93
105
|
document.addEventListener("click", onClick);
|
|
94
106
|
cleanups.push(() => document.removeEventListener("click", onClick));
|
|
@@ -109,7 +121,16 @@ export function router(routes, options = {}) {
|
|
|
109
121
|
const url = new URL(a.href, location.href);
|
|
110
122
|
if (url.origin !== location.origin)
|
|
111
123
|
return;
|
|
112
|
-
|
|
124
|
+
// Foreign-base links escape SPA prefetch entirely — the manifest
|
|
125
|
+
// only knows base-free route paths and would never match
|
|
126
|
+
// "/mado/docs". Mirrors the click-interception check above.
|
|
127
|
+
const b = appBase;
|
|
128
|
+
if (b !== "/" && !(url.pathname === b.slice(0, -1) || url.pathname.startsWith(b))) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
// The prefetch hook is fed manifest-shaped paths (no base),
|
|
132
|
+
// matching the route signal and loader registry.
|
|
133
|
+
options.prefetch(stripBase(url.pathname));
|
|
113
134
|
}
|
|
114
135
|
catch {
|
|
115
136
|
/* noop */
|
|
@@ -140,15 +161,18 @@ export function router(routes, options = {}) {
|
|
|
140
161
|
},
|
|
141
162
|
path,
|
|
142
163
|
navigate(to, opts) {
|
|
164
|
+
// `to` is a ROUTE path (no base). Re-add the active base before we
|
|
165
|
+
// touch history so the browser URL has the correct prefix.
|
|
166
|
+
const url = toBrowserUrl(to);
|
|
143
167
|
const apply = () => {
|
|
144
168
|
if (useScrollRestoration)
|
|
145
169
|
saveScroll(scrollPositions, currentScrollKey);
|
|
146
170
|
if (opts?.replace)
|
|
147
|
-
history.replaceState(null, "",
|
|
171
|
+
history.replaceState(null, "", url);
|
|
148
172
|
else
|
|
149
|
-
history.pushState(null, "",
|
|
173
|
+
history.pushState(null, "", url);
|
|
150
174
|
currentScrollKey = locationKey();
|
|
151
|
-
path.set(location.pathname);
|
|
175
|
+
path.set(stripBase(location.pathname));
|
|
152
176
|
// An in-page #hash must scroll to its target even when the pathname is
|
|
153
177
|
// unchanged (signal dedup would otherwise swallow the navigation and
|
|
154
178
|
// leave anchor links dead). (FABLE_REPORT.md finding #9)
|
|
@@ -228,10 +252,11 @@ function defaultFallback() {
|
|
|
228
252
|
export function navigate(to, opts) {
|
|
229
253
|
if (typeof history === "undefined" || typeof window === "undefined")
|
|
230
254
|
return;
|
|
255
|
+
const url = toBrowserUrl(to);
|
|
231
256
|
if (opts?.replace)
|
|
232
|
-
history.replaceState(null, "",
|
|
257
|
+
history.replaceState(null, "", url);
|
|
233
258
|
else
|
|
234
|
-
history.pushState(null, "",
|
|
259
|
+
history.pushState(null, "", url);
|
|
235
260
|
// popstate is NOT dispatched automatically on pushState/replaceState,
|
|
236
261
|
// so we dispatch it manually — all active routers will hear and update.
|
|
237
262
|
window.dispatchEvent(new PopStateEvent("popstate"));
|
|
@@ -244,6 +269,30 @@ export function navigate(to, opts) {
|
|
|
244
269
|
function locationKey() {
|
|
245
270
|
return `${location.pathname}${location.search}${location.hash}`;
|
|
246
271
|
}
|
|
272
|
+
/**
|
|
273
|
+
* Convert a route path + optional query/hash into a full browser URL with
|
|
274
|
+
* the active Vite base re-applied. Pure: no DOM access beyond the
|
|
275
|
+
* resolved `appBase` constant.
|
|
276
|
+
*/
|
|
277
|
+
function toBrowserUrl(to) {
|
|
278
|
+
if (!to)
|
|
279
|
+
return withBase("/");
|
|
280
|
+
let path = to;
|
|
281
|
+
let suffix = "";
|
|
282
|
+
const hashAt = path.indexOf("#");
|
|
283
|
+
if (hashAt >= 0) {
|
|
284
|
+
suffix = path.slice(hashAt) + suffix;
|
|
285
|
+
path = path.slice(0, hashAt);
|
|
286
|
+
}
|
|
287
|
+
const queryAt = path.indexOf("?");
|
|
288
|
+
if (queryAt >= 0) {
|
|
289
|
+
suffix = path.slice(queryAt) + suffix;
|
|
290
|
+
path = path.slice(0, queryAt);
|
|
291
|
+
}
|
|
292
|
+
if (!path)
|
|
293
|
+
path = "/";
|
|
294
|
+
return withBase(path) + suffix;
|
|
295
|
+
}
|
|
247
296
|
function saveScroll(positions, key) {
|
|
248
297
|
const maybeWindow = window;
|
|
249
298
|
positions.set(key, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navigation.js","sourceRoot":"","sources":["../../../src/router/navigation.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"navigation.js","sourceRoot":"","sources":["../../../src/router/navigation.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Browser integration: History API, click interception, hover-prefetch,\n * View Transitions, queryParam.\n *\n * Everything that touches `window` / `document` / `history` lives here,\n * so match.ts remains clean and testable without jsdom.\n */\n\nimport { signal, type Signal } from \"./../signal.js\";\nimport { html } from \"../html/template.js\";\nimport {\n compile,\n matchRoute,\n type CompiledRoute,\n type RouteParams,\n type Routes,\n} from \"./match.js\";\nimport { appBase, stripBase, withBase } from \"./base.js\";\nimport type { TemplateResult } from \"../html/template-types.js\";\n\n// ---------- router() ----------\n\nexport interface RouterApi {\n /** Signal function that returns the current TemplateResult. */\n view: () => TemplateResult;\n /** Current path as a signal. */\n path: () => string;\n /** Programmatic navigation. */\n navigate(to: string, opts?: { replace?: boolean }): void;\n /** Remove all listeners and release resources. */\n dispose(): void;\n}\n\nexport interface RouterOptions {\n /**\n * Use the View Transitions API on navigation (smooth crossfade).\n * Default `true` — if the browser doesn't support it, safely\n * falls back to a plain set().\n */\n viewTransitions?: boolean;\n /**\n * Hook for hover prefetch. Receives the pathname of the candidate\n * (without origin, query/hash stripped). Used by routes()\n * to register loaders; raw router() doesn't normally need this.\n */\n prefetch?: (pathname: string) => void;\n /**\n * Restore saved scroll on back/forward and scroll new navigations to top.\n * Default true.\n */\n scrollRestoration?: boolean;\n /**\n * Move focus to the main content landmark after navigation.\n * Default true.\n */\n focusManagement?: boolean;\n}\n\n/**\n * Minimal History API router.\n *\n * const route = router({\n * '/': () => html`<x-home/>`,\n * '/users/:id': ({ id }) => html`<x-user .id=${id}/>`,\n * '*': () => html`<x-404/>`,\n * });\n *\n * html`<main>${route.view}</main>`\n *\n * Lifecycle: subscribes to popstate + intercepts clicks\n * on `<a data-link>` + hover-prefetch (if hook given). All this\n * is removed in `dispose()` — mandatory to call in tests and\n * dev-overlay, otherwise listener leak.\n */\nexport function router(\n routes: Routes,\n options: RouterOptions = {},\n): RouterApi {\n const useViewTransitions = options.viewTransitions !== false;\n const useScrollRestoration = options.scrollRestoration !== false;\n const useFocusManagement = options.focusManagement !== false;\n const compiled = Object.entries(routes).map(([p, h]) => compile(p, h));\n const fallback =\n compiled.find((r) => r.pattern === \"*\") ?? defaultFallback();\n\n // Route pathname = browser pathname with the active Vite base stripped.\n // The route matcher, route signal and any `path()` consumer always see\n // base-free paths; `withBase()` re-adds it when we touch history.\n const path = signal(stripBase(location.pathname));\n const cleanups: Array<() => void> = [];\n const scrollPositions = new Map<string, { top: number; left: number }>();\n let currentScrollKey = locationKey();\n let disposed = false;\n\n const hist = history as History & { scrollRestoration?: \"auto\" | \"manual\" };\n const previousScrollRestoration = hist.scrollRestoration;\n if (useScrollRestoration && \"scrollRestoration\" in hist) {\n try {\n hist.scrollRestoration = \"manual\";\n cleanups.push(() => {\n hist.scrollRestoration = previousScrollRestoration;\n });\n } catch {\n /* noop */\n }\n }\n\n // -- popstate\n const onPop = () => {\n if (disposed) return;\n if (useScrollRestoration) saveScroll(scrollPositions, currentScrollKey);\n currentScrollKey = locationKey();\n path.set(stripBase(location.pathname));\n if (useScrollRestoration) restoreScroll(scrollPositions, currentScrollKey);\n if (useFocusManagement) scheduleFocusReset();\n };\n window.addEventListener(\"popstate\", onPop);\n cleanups.push(() => window.removeEventListener(\"popstate\", onPop));\n\n // -- global click interception on <a data-link>\n const onClick = (e: Event) => {\n if (disposed) return;\n const a = findAnchor(e, \"a[data-link]\");\n if (!a) return;\n if ((e as MouseEvent).defaultPrevented) return;\n if ((e as MouseEvent).button !== 0) return;\n const me = e as MouseEvent;\n if (me.metaKey || me.ctrlKey || me.shiftKey || me.altKey) return;\n // Respect intentional non-SPA links: opening in a new tab/window or a\n // download must keep native behaviour. (FABLE_REPORT.md finding #9)\n const target = a.getAttribute(\"target\");\n if (target && target !== \"_self\") return;\n if (a.hasAttribute(\"download\")) return;\n const url = new URL(a.href, location.href);\n if (url.origin !== location.origin) return;\n // Foreign-base links escape SPA navigation entirely so the browser\n // performs a real document load (avoids matching \"/other/...\" against\n // routes registered under base \"/mado/\").\n const b = appBase;\n if (b !== \"/\" && !(url.pathname === b.slice(0, -1) || url.pathname.startsWith(b))) {\n return;\n }\n e.preventDefault();\n const routePath = stripBase(url.pathname);\n api.navigate(routePath + url.search + url.hash);\n };\n document.addEventListener(\"click\", onClick);\n cleanups.push(() => document.removeEventListener(\"click\", onClick));\n\n // -- hover-prefetch (>=50ms on <a data-link:not([data-no-prefetch])>)\n let prefetchTimer: ReturnType<typeof setTimeout> | null = null;\n const onMouseOver = (e: Event) => {\n if (disposed) return;\n if (!options.prefetch) return;\n const a = findAnchor(e, \"a[data-link]:not([data-no-prefetch])\");\n if (!a) return;\n if (prefetchTimer) clearTimeout(prefetchTimer);\n prefetchTimer = setTimeout(() => {\n try {\n const url = new URL(a.href, location.href);\n if (url.origin !== location.origin) return;\n // Foreign-base links escape SPA prefetch entirely — the manifest\n // only knows base-free route paths and would never match\n // \"/mado/docs\". Mirrors the click-interception check above.\n const b = appBase;\n if (b !== \"/\" && !(url.pathname === b.slice(0, -1) || url.pathname.startsWith(b))) {\n return;\n }\n // The prefetch hook is fed manifest-shaped paths (no base),\n // matching the route signal and loader registry.\n options.prefetch!(stripBase(url.pathname));\n } catch {\n /* noop */\n }\n }, 50);\n };\n const onMouseOut = () => {\n if (prefetchTimer) {\n clearTimeout(prefetchTimer);\n prefetchTimer = null;\n }\n };\n document.addEventListener(\"mouseover\", onMouseOver);\n document.addEventListener(\"mouseout\", onMouseOut);\n cleanups.push(() => {\n document.removeEventListener(\"mouseover\", onMouseOver);\n document.removeEventListener(\"mouseout\", onMouseOut);\n if (prefetchTimer) clearTimeout(prefetchTimer);\n });\n\n const api: RouterApi = {\n view: () => {\n const p = path();\n const m = matchRoute(p, compiled);\n if (m) return m.route.handler(m.params);\n return fallback.handler({});\n },\n path,\n navigate(to, opts) {\n // `to` is a ROUTE path (no base). Re-add the active base before we\n // touch history so the browser URL has the correct prefix.\n const url = toBrowserUrl(to);\n const apply = () => {\n if (useScrollRestoration) saveScroll(scrollPositions, currentScrollKey);\n if (opts?.replace) history.replaceState(null, \"\", url);\n else history.pushState(null, \"\", url);\n currentScrollKey = locationKey();\n path.set(stripBase(location.pathname));\n // An in-page #hash must scroll to its target even when the pathname is\n // unchanged (signal dedup would otherwise swallow the navigation and\n // leave anchor links dead). (FABLE_REPORT.md finding #9)\n if (location.hash) scrollToHash(location.hash);\n else if (useScrollRestoration) scrollToTop();\n if (useFocusManagement) scheduleFocusReset();\n };\n\n // View Transitions API: smooth crossfade between pages,\n // if the browser supports it. Psychologically removes flashing\n // even if the new page renders in 50-100ms.\n const doc = document as Document & {\n startViewTransition?: (cb: () => void) => unknown;\n };\n if (useViewTransitions && typeof doc.startViewTransition === \"function\") {\n doc.startViewTransition(apply);\n } else {\n apply();\n }\n },\n dispose() {\n if (disposed) return;\n disposed = true;\n for (const c of cleanups.splice(0)) {\n try {\n c();\n } catch {\n /* noop */\n }\n }\n },\n };\n\n return api;\n}\n\nfunction findAnchor(e: Event, selector: string): HTMLAnchorElement | null {\n const fromElement = (node: unknown): HTMLAnchorElement | null => {\n if (!(node instanceof Element)) return null;\n const match = node.matches(selector) ? node : node.closest(selector);\n if (!match || !(\"href\" in match)) return null;\n return match as HTMLAnchorElement;\n };\n\n const direct = fromElement(e.target);\n if (direct) return direct;\n\n if (typeof e.composedPath !== \"function\") return null;\n for (const node of e.composedPath()) {\n const found = fromElement(node);\n if (found) return found;\n }\n return null;\n}\n\n/** Default 404, if the manifest had no `'*'`. */\nfunction defaultFallback(): CompiledRoute {\n return compile(\"*\", () => html`<pre>404: ${location.pathname}</pre>`);\n}\n\n// ---------- navigate() ----------\n\n/**\n * Global helper for programmatic navigation. Equivalent to\n * `api.navigate(to)` for any active router — updates the URL\n * via History API and dispatches `popstate`, which all\n * active routers on the page will pick up.\n *\n * import { navigate } from \"@madojs/mado\";\n * navigate(\"/users/42\");\n *\n * Used inside form handlers / events when you don't have\n * direct access to RouterApi (e.g. inside a component's setup function\n * that didn't receive the router as a parameter).\n */\nexport function navigate(to: string, opts?: { replace?: boolean }): void {\n if (typeof history === \"undefined\" || typeof window === \"undefined\") return;\n const url = toBrowserUrl(to);\n if (opts?.replace) history.replaceState(null, \"\", url);\n else history.pushState(null, \"\", url);\n // popstate is NOT dispatched automatically on pushState/replaceState,\n // so we dispatch it manually — all active routers will hear and update.\n window.dispatchEvent(new PopStateEvent(\"popstate\"));\n if (location.hash) scrollToHash(location.hash);\n else scrollToTop();\n scheduleFocusReset();\n}\n\nfunction locationKey(): string {\n return `${location.pathname}${location.search}${location.hash}`;\n}\n\n/**\n * Convert a route path + optional query/hash into a full browser URL with\n * the active Vite base re-applied. Pure: no DOM access beyond the\n * resolved `appBase` constant.\n */\nfunction toBrowserUrl(to: string): string {\n if (!to) return withBase(\"/\");\n let path = to;\n let suffix = \"\";\n const hashAt = path.indexOf(\"#\");\n if (hashAt >= 0) {\n suffix = path.slice(hashAt) + suffix;\n path = path.slice(0, hashAt);\n }\n const queryAt = path.indexOf(\"?\");\n if (queryAt >= 0) {\n suffix = path.slice(queryAt) + suffix;\n path = path.slice(0, queryAt);\n }\n if (!path) path = \"/\";\n return withBase(path) + suffix;\n}\n\nfunction saveScroll(\n positions: Map<string, { top: number; left: number }>,\n key: string,\n): void {\n const maybeWindow = window as Window & {\n scrollX?: number;\n scrollY?: number;\n pageXOffset?: number;\n pageYOffset?: number;\n };\n positions.set(key, {\n left: maybeWindow.scrollX ?? maybeWindow.pageXOffset ?? 0,\n top: maybeWindow.scrollY ?? maybeWindow.pageYOffset ?? 0,\n });\n}\n\nfunction restoreScroll(\n positions: Map<string, { top: number; left: number }>,\n key: string,\n): void {\n const pos = positions.get(key) ?? { top: 0, left: 0 };\n scrollTo(pos);\n}\n\nfunction scrollToTop(): void {\n scrollTo({ top: 0, left: 0 });\n}\n\nfunction scrollToHash(hash: string): void {\n const scroll = () => {\n const target = hashTarget(hash);\n if (!target) return false;\n try {\n target.scrollIntoView({ block: \"start\", inline: \"nearest\" });\n } catch {\n try {\n target.scrollIntoView();\n } catch {\n /* noop */\n }\n }\n return true;\n };\n\n if (scroll()) return;\n // New-route hash targets are often rendered by the reactive route effect\n // after `path.set()`, so try once more on the next microtask.\n queueMicrotask(() => {\n scroll();\n });\n}\n\nfunction hashTarget(hash: string): HTMLElement | null {\n const raw = hash.startsWith(\"#\") ? hash.slice(1) : hash;\n if (!raw) return null;\n let id = raw;\n try {\n id = decodeURIComponent(raw);\n } catch {\n /* keep raw hash text */\n }\n return document.getElementById(id);\n}\n\nfunction scrollTo(options: ScrollToOptions): void {\n const maybeWindow = window as Window & {\n scrollTo?: (options: ScrollToOptions) => void;\n };\n if (typeof maybeWindow.scrollTo !== \"function\") return;\n try {\n maybeWindow.scrollTo(options);\n } catch {\n /* noop */\n }\n}\n\nfunction scheduleFocusReset(): void {\n queueMicrotask(() => {\n const target = document.querySelector(\n \"[data-mado-focus], main, [role='main'], h1\",\n );\n if (!(target instanceof HTMLElement)) return;\n if (!target.hasAttribute(\"tabindex\")) target.setAttribute(\"tabindex\", \"-1\");\n try {\n target.focus({ preventScroll: true });\n } catch {\n try {\n target.focus();\n } catch {\n /* noop */\n }\n }\n });\n}\n\n// ---------- queryParam ----------\n//\n// Reactive wrapper over ?foo=bar. Reading → signal, .set() → replaceState.\n// All queryParams in the app are synchronised via a shared signal bus.\n// The bus is lazily initialised on first queryParam() call, because\n// in SSR/test environments window/location may be connected later.\n\nlet queryBus: Signal<string> | null = null;\n\nfunction ensureQueryBus(): Signal<string> {\n if (queryBus) return queryBus;\n queryBus = signal(location.search);\n window.addEventListener(\"popstate\", () => queryBus!.set(location.search));\n return queryBus;\n}\n\nfunction syncQuery(next: URLSearchParams, push: boolean): void {\n const url = `${location.pathname}?${next.toString()}${location.hash}`.replace(\n /\\?$/,\n \"\",\n );\n if (push) history.pushState(null, \"\", url);\n else history.replaceState(null, \"\", url);\n ensureQueryBus().set(location.search);\n}\n\nexport interface QueryParam {\n (): string;\n set(value: string | null, opts?: { push?: boolean }): void;\n}\n\n/**\n * Reactive query parameter.\n *\n * const page = queryParam('page', '1');\n * page(); // '1' (or current URL value)\n * page.set('2'); // history.replaceState and re-render\n * page.set(null); // delete the parameter\n */\nexport function queryParam(name: string, defaultValue = \"\"): QueryParam {\n const bus = ensureQueryBus();\n const read = (() => {\n const search = bus();\n const params = new URLSearchParams(search);\n return params.get(name) ?? defaultValue;\n }) as QueryParam;\n\n read.set = (value, opts) => {\n const params = new URLSearchParams(location.search);\n if (value === null || value === \"\") params.delete(name);\n else params.set(name, value);\n syncQuery(params, opts?.push ?? false);\n };\n\n return read;\n}\n\n/**\n * For typing purposes — same characteristics as Signal<string>.\n * Convenient in places that expect a plain signal.\n */\nexport type QuerySignal = Signal<string>;\n"]}
|
package/dist/src/signal.d.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signal.d.ts","sourceRoot":"","sources":["../../src/signal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAyIH;;;GAGG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAiBvC;AAED;;;GAGG;AACH,wBAAgB,SAAS,IAAI,IAAI,CAEhC;AAKD,MAAM,WAAW,MAAM,CAAC,CAAC;IACvB,IAAI,CAAC,CAAC;IACN,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;IACpB,MAAM,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;IACtC,IAAI,IAAI,CAAC,CAAC;CACX;AAED,wBAAgB,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAyC/C;AAKD,MAAM,WAAW,QAAQ,CAAC,CAAC;IACzB,IAAI,CAAC,CAAC;IACN,IAAI,IAAI,CAAC,CAAC;CACX;AAED,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC;CACxC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EACxB,EAAE,EAAE,MAAM,CAAC,EACX,OAAO,GAAE,eAAe,CAAC,CAAC,CAAM,GAC/B,QAAQ,CAAC,CAAC,CAAC,CA2Hb;AAID,MAAM,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC;AAElC,wBAAgB,MAAM,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,QAAQ,GAAG,QAAQ,CA6C1D;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAQ3C"}
|
package/dist/src/signal.js
CHANGED
|
@@ -23,6 +23,9 @@
|
|
|
23
23
|
*
|
|
24
24
|
* batch(() => { a.set(1); b.set(2); });
|
|
25
25
|
*/
|
|
26
|
+
import { reportError } from "./diagnostics.js";
|
|
27
|
+
import { getCurrentLifecycle } from "./lifecycle.js";
|
|
28
|
+
import { emitDevtools } from "./devtools-hook.js";
|
|
26
29
|
const MAX_FLUSH_RUNS_PER_SUBSCRIBER = 100;
|
|
27
30
|
let activeTracker = null;
|
|
28
31
|
class SubscriberSet extends Set {
|
|
@@ -84,8 +87,7 @@ function drainDeferredEquals() {
|
|
|
84
87
|
fn();
|
|
85
88
|
}
|
|
86
89
|
catch (err) {
|
|
87
|
-
|
|
88
|
-
console.error("[mado] deferred computed reconcile threw:", err);
|
|
90
|
+
reportError("reactivity", "computed-reconcile", "deferred computed reconcile threw", err);
|
|
89
91
|
}
|
|
90
92
|
}
|
|
91
93
|
}
|
|
@@ -113,9 +115,7 @@ function flush() {
|
|
|
113
115
|
const runs = (runCounts.get(sub) ?? 0) + 1;
|
|
114
116
|
runCounts.set(sub, runs);
|
|
115
117
|
if (runs > MAX_FLUSH_RUNS_PER_SUBSCRIBER) {
|
|
116
|
-
|
|
117
|
-
console.error("[mado] effect cycle detected: subscriber re-ran more than " +
|
|
118
|
-
`${MAX_FLUSH_RUNS_PER_SUBSCRIBER} times in one flush.`);
|
|
118
|
+
reportError("reactivity", "effect-cycle", `effect cycle detected: subscriber re-ran more than ${MAX_FLUSH_RUNS_PER_SUBSCRIBER} times in one flush`, undefined);
|
|
119
119
|
continue;
|
|
120
120
|
}
|
|
121
121
|
try {
|
|
@@ -123,8 +123,7 @@ function flush() {
|
|
|
123
123
|
}
|
|
124
124
|
catch (err) {
|
|
125
125
|
// a subscriber must not crash the others
|
|
126
|
-
|
|
127
|
-
console.error("[mado] effect threw:", err);
|
|
126
|
+
reportError("reactivity", "effect-run", "effect threw", err);
|
|
128
127
|
}
|
|
129
128
|
}
|
|
130
129
|
}
|
|
@@ -171,7 +170,10 @@ export function signal(initial) {
|
|
|
171
170
|
read.set = (next) => {
|
|
172
171
|
if (Object.is(value, next))
|
|
173
172
|
return;
|
|
173
|
+
const previous = value;
|
|
174
174
|
value = next;
|
|
175
|
+
if (typeof __MADO_DEVTOOLS__ === "undefined" || __MADO_DEVTOOLS__)
|
|
176
|
+
emitDevtools("signal:set", read, { previous, value: next });
|
|
175
177
|
// snapshot: a subscriber may re-subscribe in run(), mutating the Set
|
|
176
178
|
const snapshot = [...subscribers];
|
|
177
179
|
// sync subscribers (computed) first — mark dirty before effects read;
|
|
@@ -182,8 +184,7 @@ export function signal(initial) {
|
|
|
182
184
|
e.run();
|
|
183
185
|
}
|
|
184
186
|
catch (err) {
|
|
185
|
-
|
|
186
|
-
console.error("[mado] sync subscriber threw:", err);
|
|
187
|
+
reportError("reactivity", "sync-subscriber", "sync subscriber threw", err);
|
|
187
188
|
}
|
|
188
189
|
}
|
|
189
190
|
}
|
|
@@ -195,6 +196,8 @@ export function signal(initial) {
|
|
|
195
196
|
read.update = (fn) => read.set(fn(value));
|
|
196
197
|
read.peek = () => value;
|
|
197
198
|
debugInfo.set(read, { subscribers });
|
|
199
|
+
if (typeof __MADO_DEVTOOLS__ === "undefined" || __MADO_DEVTOOLS__)
|
|
200
|
+
emitDevtools("signal:create", read, { value });
|
|
198
201
|
return read;
|
|
199
202
|
}
|
|
200
203
|
/**
|
|
@@ -286,8 +289,7 @@ export function computed(fn, options = {}) {
|
|
|
286
289
|
e.run();
|
|
287
290
|
}
|
|
288
291
|
catch (err) {
|
|
289
|
-
|
|
290
|
-
console.error("[mado] sync subscriber threw:", err);
|
|
292
|
+
reportError("reactivity", "sync-subscriber", "sync subscriber threw", err);
|
|
291
293
|
}
|
|
292
294
|
}
|
|
293
295
|
else {
|
|
@@ -312,6 +314,8 @@ export function computed(fn, options = {}) {
|
|
|
312
314
|
}
|
|
313
315
|
dirty = false;
|
|
314
316
|
hasValue = true;
|
|
317
|
+
if (typeof __MADO_DEVTOOLS__ === "undefined" || __MADO_DEVTOOLS__)
|
|
318
|
+
emitDevtools("computed:value", read, { value });
|
|
315
319
|
queueSuspendIfUnobserved();
|
|
316
320
|
};
|
|
317
321
|
const read = (() => {
|
|
@@ -329,19 +333,32 @@ export function computed(fn, options = {}) {
|
|
|
329
333
|
return value;
|
|
330
334
|
};
|
|
331
335
|
debugInfo.set(read, { subscribers, tracker });
|
|
336
|
+
if (typeof __MADO_DEVTOOLS__ === "undefined" || __MADO_DEVTOOLS__)
|
|
337
|
+
emitDevtools("computed:create", read);
|
|
332
338
|
return read;
|
|
333
339
|
}
|
|
334
340
|
export function effect(fn) {
|
|
335
341
|
let cleanup;
|
|
342
|
+
let disposed = false;
|
|
336
343
|
const run = () => {
|
|
344
|
+
if (disposed)
|
|
345
|
+
return;
|
|
346
|
+
if (typeof __MADO_DEVTOOLS__ === "undefined" || __MADO_DEVTOOLS__)
|
|
347
|
+
emitDevtools("effect:run", run);
|
|
337
348
|
cleanupTracker(tracker);
|
|
338
|
-
|
|
339
|
-
|
|
349
|
+
const previousCleanup = cleanup;
|
|
350
|
+
cleanup = undefined;
|
|
351
|
+
if (typeof previousCleanup === "function")
|
|
352
|
+
previousCleanup();
|
|
340
353
|
const prev = activeTracker;
|
|
341
354
|
activeTracker = tracker;
|
|
342
355
|
try {
|
|
343
356
|
cleanup = fn();
|
|
344
357
|
}
|
|
358
|
+
catch (err) {
|
|
359
|
+
cleanupTracker(tracker);
|
|
360
|
+
throw err;
|
|
361
|
+
}
|
|
345
362
|
finally {
|
|
346
363
|
activeTracker = prev;
|
|
347
364
|
}
|
|
@@ -350,12 +367,24 @@ export function effect(fn) {
|
|
|
350
367
|
deps: new Set(),
|
|
351
368
|
entry: { run, sync: false },
|
|
352
369
|
};
|
|
353
|
-
|
|
354
|
-
|
|
370
|
+
const dispose = () => {
|
|
371
|
+
if (disposed)
|
|
372
|
+
return;
|
|
373
|
+
disposed = true;
|
|
374
|
+
pending.delete(run);
|
|
355
375
|
cleanupTracker(tracker);
|
|
356
|
-
|
|
357
|
-
|
|
376
|
+
const finalCleanup = cleanup;
|
|
377
|
+
cleanup = undefined;
|
|
378
|
+
if (typeof finalCleanup === "function")
|
|
379
|
+
finalCleanup();
|
|
380
|
+
if (typeof __MADO_DEVTOOLS__ === "undefined" || __MADO_DEVTOOLS__)
|
|
381
|
+
emitDevtools("effect:dispose", run);
|
|
358
382
|
};
|
|
383
|
+
if (typeof __MADO_DEVTOOLS__ === "undefined" || __MADO_DEVTOOLS__)
|
|
384
|
+
emitDevtools("effect:create", run);
|
|
385
|
+
run();
|
|
386
|
+
getCurrentLifecycle()?.onDispose(dispose);
|
|
387
|
+
return dispose;
|
|
359
388
|
}
|
|
360
389
|
/**
|
|
361
390
|
* Execute a function outside of tracking — reading signals will not create a subscription.
|