@manyducks.co/dolla 2.0.0 → 3.1.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 +133 -284
- package/dist/context-B5blupD2.js +363 -0
- package/dist/context-B5blupD2.js.map +1 -0
- package/dist/core/context.d.ts +29 -144
- package/dist/core/debug.d.ts +19 -0
- package/dist/core/index.d.ts +15 -16
- package/dist/core/markup/helpers.d.ts +34 -0
- package/dist/core/markup/html.d.ts +3 -0
- package/dist/core/{nodes → markup/nodes}/dom.d.ts +5 -4
- package/dist/core/markup/nodes/dynamic.d.ts +16 -0
- package/dist/core/markup/nodes/element.d.ts +14 -0
- package/dist/core/markup/nodes/portal.d.ts +15 -0
- package/dist/core/markup/nodes/repeat.d.ts +21 -0
- package/dist/core/markup/nodes/view.d.ts +17 -0
- package/dist/core/markup/scheduler.d.ts +1 -0
- package/dist/core/markup/types.d.ts +62 -0
- package/dist/core/markup/utils.d.ts +22 -0
- package/dist/core/ref.d.ts +6 -12
- package/dist/core/root.d.ts +36 -0
- package/dist/core/signals.d.ts +46 -76
- package/dist/core/symbols.d.ts +2 -0
- package/dist/core-JHktdqjt.js +242 -0
- package/dist/core-JHktdqjt.js.map +1 -0
- package/dist/http/index.d.ts +21 -33
- package/dist/http.js +89 -149
- package/dist/http.js.map +1 -1
- package/dist/index.js +4 -174
- package/dist/jsx-dev-runtime.d.ts +4 -3
- package/dist/jsx-dev-runtime.js +12 -9
- package/dist/jsx-dev-runtime.js.map +1 -1
- package/dist/jsx-runtime.d.ts +5 -4
- package/dist/jsx-runtime.js +17 -12
- package/dist/jsx-runtime.js.map +1 -1
- package/dist/router/index.d.ts +4 -3
- package/dist/router/router.d.ts +19 -162
- package/dist/router/store.d.ts +12 -0
- package/dist/router/types.d.ts +152 -0
- package/dist/router/utils.d.ts +99 -0
- package/dist/router/utils.test.d.ts +1 -0
- package/dist/router.js +428 -5
- package/dist/router.js.map +1 -1
- package/dist/signals-CMJPGr_M.js +354 -0
- package/dist/signals-CMJPGr_M.js.map +1 -0
- package/dist/translate/index.d.ts +82 -0
- package/dist/translate.js +125 -0
- package/dist/translate.js.map +1 -0
- package/dist/types.d.ts +21 -39
- package/dist/utils.d.ts +41 -29
- package/dist/utils.test.d.ts +1 -0
- package/dist/virtual/index.d.ts +1 -0
- package/dist/virtual/list.d.ts +53 -0
- package/package.json +19 -16
- package/dist/core/app.d.ts +0 -24
- package/dist/core/env.d.ts +0 -3
- package/dist/core/hooks.d.ts +0 -70
- package/dist/core/logger.d.ts +0 -42
- package/dist/core/logger.test.d.ts +0 -0
- package/dist/core/markup.d.ts +0 -82
- package/dist/core/markup.test.d.ts +0 -0
- package/dist/core/nodes/_markup.d.ts +0 -36
- package/dist/core/nodes/dynamic.d.ts +0 -22
- package/dist/core/nodes/element.d.ts +0 -27
- package/dist/core/nodes/portal.d.ts +0 -18
- package/dist/core/nodes/repeat.d.ts +0 -27
- package/dist/core/nodes/view.d.ts +0 -25
- package/dist/core/views/default-crash-view.d.ts +0 -25
- package/dist/core/views/for.d.ts +0 -21
- package/dist/core/views/fragment.d.ts +0 -7
- package/dist/core/views/portal.d.ts +0 -16
- package/dist/core/views/show.d.ts +0 -25
- package/dist/fragment-BahD_BJA.js +0 -7
- package/dist/fragment-BahD_BJA.js.map +0 -1
- package/dist/i18n/index.d.ts +0 -134
- package/dist/i18n.js +0 -309
- package/dist/i18n.js.map +0 -1
- package/dist/index-DRJlxs-Q.js +0 -535
- package/dist/index-DRJlxs-Q.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/logger-Aqi9m1CF.js +0 -565
- package/dist/logger-Aqi9m1CF.js.map +0 -1
- package/dist/markup-8jNhoqDe.js +0 -1089
- package/dist/markup-8jNhoqDe.js.map +0 -1
- package/dist/router/hooks.d.ts +0 -2
- package/dist/router/router.utils.d.ts +0 -93
- package/dist/typeChecking-5kmX0ulW.js +0 -65
- package/dist/typeChecking-5kmX0ulW.js.map +0 -1
- package/dist/typeChecking.d.ts +0 -95
- package/docs/buildless.md +0 -132
- package/docs/components.md +0 -238
- package/docs/hooks.md +0 -356
- package/docs/http.md +0 -178
- package/docs/i18n.md +0 -220
- package/docs/index.md +0 -10
- package/docs/markup.md +0 -136
- package/docs/mixins.md +0 -176
- package/docs/ref.md +0 -77
- package/docs/router.md +0 -281
- package/docs/setup.md +0 -137
- package/docs/signals.md +0 -262
- package/docs/stores.md +0 -113
- package/docs/views.md +0 -356
- package/notes/atomic.md +0 -452
- package/notes/elimination.md +0 -33
- package/notes/observable.md +0 -180
- package/notes/scratch.md +0 -565
- package/notes/splitting.md +0 -5
- package/notes/views.md +0 -195
- package/vite.config.js +0 -22
- /package/dist/core/{hooks.test.d.ts → markup/html.test.d.ts} +0 -0
- /package/dist/core/{ref.test.d.ts → markup/utils.test.d.ts} +0 -0
- /package/dist/router/{router.utils.test.d.ts → matcher.test.d.ts} +0 -0
- /package/dist/{typeChecking.test.d.ts → router/router.test.d.ts} +0 -0
package/dist/router.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
|
1
|
+
{"version":3,"file":"router.js","names":[],"sources":["../src/router/utils.ts","../src/router/store.ts","../src/router/router.ts","../src/router/index.ts"],"sourcesContent":["import { View } from \"../types.js\";\nimport { assert, isArray, isFunction, isObject, isString, uniqueId } from \"../utils.js\";\nimport type { JourneyStep, Route, RouteLayer, Stringable } from \"./types.js\";\n\nexport interface Match {\n /**\n * The path string that triggered this match.\n */\n path: string;\n\n /**\n * The pattern satisfied by `path`.\n */\n pattern: string;\n\n /**\n * Named params as parsed from `path`.\n */\n params: Record<string, string>;\n\n /**\n * Query params as parsed from `path`.\n */\n query: Record<string, string>;\n\n /**\n * Freeform data you wish to store with this route.\n * Merged `data` from all matched layers are available on the router's `match.meta`.\n */\n meta: Record<any, any>;\n}\n\nexport interface RouteMatch extends Match {\n layers: RouteLayer[];\n redirect?: string | ((match: Match) => string) | ((match: Match) => Promise<string>);\n}\n\nexport type RoutePayload = {\n pattern: string;\n meta: Record<any, any>;\n layers?: RouteLayer[];\n redirect?: string | ((match: Match) => string) | ((match: Match) => Promise<string>);\n};\n\nexport type RouteMatchOptions = {\n willMatch?: (route: RoutePayload) => boolean;\n};\n\n/**\n * Separates a URL path into multiple fragments.\n *\n * @param path - A path string (e.g. `\"/api/users/5\"`)\n * @returns an array of fragments (e.g. `[\"api\", \"users\", \"5\"]`)\n */\nexport function splitPath(path: string): string[] {\n return path\n .split(\"/\")\n .map((f) => f.trim())\n .filter(Boolean);\n}\n\n/**\n * Joins multiple URL path fragments into a single string.\n *\n * @param parts - One or more URL fragments (e.g. `[\"api\", \"users\", 5]`)\n * @returns a joined path (e.g. `\"api/users/5\"`)\n */\n\nexport function joinPath(parts: { toString(): string }[]): string {\n const joined = parts\n .map((p) => p.toString())\n .filter(Boolean)\n .join(\"/\");\n if (!joined) return \"\";\n\n const isAbsolute = joined.startsWith(\"/\");\n const segments = joined.split(\"/\");\n const resolved: string[] = [];\n\n for (const segment of segments) {\n if (segment === \"\" || segment === \".\") continue;\n if (segment === \"..\") {\n // Pop the previous segment unless we're at the root, or already backing up\n if (resolved.length > 0 && resolved[resolved.length - 1] !== \"..\") {\n resolved.pop();\n } else if (!isAbsolute) {\n resolved.push(\"..\");\n }\n } else {\n resolved.push(segment);\n }\n }\n\n let result = resolved.join(\"/\");\n if (isAbsolute) result = \"/\" + result;\n\n return result || (isAbsolute ? \"/\" : \"\");\n}\n\nexport function resolvePath(base: string, part: string | null = null): string {\n if (part == null) {\n part = base;\n base = \"\";\n }\n\n // If the target is absolute, it replaces the base entirely\n if (part.startsWith(\"/\")) return joinPath([part]);\n\n // Otherwise, join them and let joinPath resolve the '.' and '..'\n return joinPath([base, part]);\n}\n\nexport function parseQueryParams(query: string): Record<string, string> {\n return Object.fromEntries(new URLSearchParams(query));\n}\n\nexport function mergeQueryParams(\n previous: Record<string, string>,\n current: Record<string, Stringable>,\n preserve?: boolean | string[],\n) {\n const merged: Record<string, any> = {};\n\n if (preserve === true) {\n Object.assign(merged, previous);\n } else if (isArray(preserve)) {\n for (const key of preserve) {\n if (key in previous) merged[key] = previous[key];\n }\n }\n\n Object.assign(merged, current);\n return new URLSearchParams(merged as Record<string, string>);\n}\n\nexport class RouteNode {\n staticChildren = new Map<string, RouteNode>();\n numericChild: RouteNode | null = null;\n paramChild: RouteNode | null = null;\n wildcardChild: RouteNode | null = null;\n\n // Set if this node represents the end of a valid path\n route?: RoutePayload;\n paramName?: string;\n numericName?: string;\n}\n\nexport function buildRouteTree(routes: Route[]): RouteNode {\n const root = new RouteNode();\n const redirectsToValidate: RoutePayload[] = [];\n\n function insertIntoTree(pattern: string, payload: RoutePayload) {\n const parts = splitPath(pattern);\n let current = root;\n\n for (const part of parts) {\n if (part === \"*\") {\n current = current.wildcardChild ??= new RouteNode();\n } else if (part.charCodeAt(0) === 123) {\n // {\n if (part.charCodeAt(1) === 35) {\n // #\n current = current.numericChild ??= new RouteNode();\n current.numericName = part.slice(2, -1);\n } else {\n current = current.paramChild ??= new RouteNode();\n current.paramName = part.slice(1, -1);\n }\n } else {\n const key = part.toLowerCase();\n let next = current.staticChildren.get(key);\n if (!next) current.staticChildren.set(key, (next = new RouteNode()));\n current = next;\n }\n }\n current.route = payload;\n }\n\n function parse(route: Route, parents: Route[] = [], layers: RouteLayer[] = []) {\n assert(isObject<Route>(route) && isString(route.path), \"Invalid route object\");\n\n const parentPaths = parents.map((p) => p.path);\n const parent = parents.at(-1);\n const meta = parent && route.meta ? { ...parent.meta, ...route.meta } : route.meta || {};\n\n const rawPattern = parentPaths.length ? joinPath([...parentPaths, route.path]) : route.path;\n const patterns = expandOptionalPaths(rawPattern);\n\n if (route.redirect) {\n assert(!route.routes && !route.view, \"Route cannot mix redirect with view/routes\");\n let redirect = route.redirect;\n\n if (isString(redirect)) {\n redirect = resolvePath(joinPath(parentPaths), redirect);\n if (!redirect.startsWith(\"/\")) redirect = \"/\" + redirect;\n }\n\n for (const pattern of patterns) {\n const payload: RoutePayload = { pattern, meta, redirect };\n insertIntoTree(pattern, payload);\n if (isString(redirect)) redirectsToValidate.push(payload);\n }\n\n return;\n }\n\n assert(route.view || route.routes, \"Route must have view, redirect, or routes\");\n\n let view = (route.view || ((props: any) => props.children)) as View<any>;\n if (!isFunction(view) && !(view as any)._lazy) {\n throw new TypeError(`Expected view function for ${route.path}`);\n }\n\n if (route.routes) {\n // For parent nodes, create the layer using the raw pattern and recurse\n const layer: RouteLayer = {\n id: uniqueId(),\n pattern: rawPattern,\n view,\n preload: route.preload,\n errorView: route.errorView,\n };\n for (const subroute of route.routes) parse(subroute, [...parents, route], [...layers, layer]);\n } else {\n // For leaf nodes, register every permutation as a valid endpoint\n for (const pattern of patterns) {\n const layer: RouteLayer = {\n id: uniqueId(),\n pattern, // Use the specific expanded pattern for this layer\n view,\n preload: route.preload,\n errorView: route.errorView,\n };\n insertIntoTree(pattern, { pattern, meta, layers: [...layers, layer] });\n }\n }\n }\n\n for (const route of routes) parse(route);\n\n for (const payload of redirectsToValidate) {\n assert(\n matchRoute(root, payload.redirect as string, { willMatch: (r) => r !== payload }),\n `Dead redirect: ${payload.pattern} -> ${payload.redirect}`,\n );\n }\n\n return root;\n}\n\nexport function matchRoute(rootNode: RouteNode, url: string, options: RouteMatchOptions = {}): RouteMatch | undefined {\n const [path, query] = url.split(\"?\");\n const parts = splitPath(path);\n const paramState: Record<string, string> = {}; // Reused across branches\n\n function search(node: RouteNode, index: number): RouteMatch | undefined {\n // if we've consumed all URL parts\n if (index === parts.length) {\n if (node.route && (!options.willMatch || options.willMatch(node.route))) {\n return {\n path: path || \"/\",\n pattern: node.route.pattern,\n params: { ...paramState },\n query: parseQueryParams(query || \"\"),\n meta: node.route.meta,\n layers: node.route.layers ?? [],\n redirect: node.route.redirect,\n };\n }\n\n // Allow wildcards to match zero remaining segments\n if (node.wildcardChild && node.wildcardChild.route) {\n if (!options.willMatch || options.willMatch(node.wildcardChild.route)) {\n return {\n path: path || \"/\",\n pattern: node.wildcardChild.route.pattern,\n params: { ...paramState, wildcard: \"/\" },\n query: parseQueryParams(query || \"\"),\n meta: node.wildcardChild.route.meta,\n layers: node.wildcardChild.route.layers ?? [],\n redirect: node.wildcardChild.route.redirect,\n };\n }\n }\n\n return undefined;\n }\n\n const part = parts[index];\n const lowerPart = part.toLowerCase();\n\n const staticNode = node.staticChildren.get(lowerPart);\n if (staticNode) {\n const result = search(staticNode, index + 1);\n if (result) return result;\n }\n\n if (node.numericChild && !isNaN(Number(part))) {\n paramState[node.numericChild.numericName!] = part;\n const result = search(node.numericChild, index + 1);\n if (result) return result;\n delete paramState[node.numericChild.numericName!];\n }\n\n if (node.paramChild) {\n paramState[node.paramChild.paramName!] = decodeURIComponent(part);\n const result = search(node.paramChild, index + 1);\n if (result) return result;\n delete paramState[node.paramChild.paramName!];\n }\n\n if (node.wildcardChild && node.wildcardChild.route) {\n if (!options.willMatch || options.willMatch(node.wildcardChild.route)) {\n return {\n path: path || \"/\",\n pattern: node.wildcardChild.route.pattern,\n params: { ...paramState, wildcard: \"/\" + parts.slice(index).map(decodeURIComponent).join(\"/\") },\n query: parseQueryParams(query || \"\"),\n meta: node.wildcardChild.route.meta,\n layers: node.wildcardChild.route.layers ?? [],\n redirect: node.wildcardChild.route.redirect,\n };\n }\n }\n\n return undefined;\n }\n\n return search(rootNode, 0);\n}\n\nexport interface ResolvedRoute {\n match?: RouteMatch;\n journey: JourneyStep[];\n}\n\n/**\n * Takes a URL and finds a match, following redirects.\n */\nexport async function resolveRoute(\n rootNode: RouteNode,\n path: string,\n journey: JourneyStep[] = [],\n): Promise<ResolvedRoute> {\n const match = matchRoute(rootNode, path);\n\n if (!match) return { journey: [...journey, { kind: \"miss\", message: `no match for '${path}'` }] };\n\n if (match.redirect != null) {\n let target = match.redirect;\n\n if (isString(target)) {\n target = replaceParams(target, match.params);\n } else {\n target = await target(match);\n assert(isString(target), \"Redirect function must return a path.\");\n if (!target.startsWith(\"/\")) target = resolvePath(match.path, target);\n }\n\n return resolveRoute(rootNode, target, [\n ...journey,\n { kind: \"redirect\", message: `redirecting '${match.path}' -> '${target}'` },\n ]);\n }\n\n // TODO: Data preload\n\n return { match, journey: [...journey, { kind: \"match\", message: `matched route '${match.path}'` }] };\n}\n\n/**\n * Intercepts links within the root node.\n *\n * This is adapted from https://github.com/choojs/nanohref/blob/master/index.js\n *\n * @param root - Element under which to intercept link clicks\n * @param callback - Function to call when a click event is intercepted\n * @param _window - (optional) Override for global window object\n */\nexport function catchLinks(\n root: Element,\n callback: (href: string, anchor: HTMLAnchorElement) => void,\n _window = window,\n) {\n function handler(e: MouseEvent) {\n if ((e.button && e.button !== 0) || e.ctrlKey || e.metaKey || e.altKey || e.shiftKey || e.defaultPrevented) return;\n\n const anchor = (e.target as Element).closest(\"a\");\n if (!anchor || !root.contains(anchor)) return;\n\n const href = anchor.getAttribute(\"href\");\n if (!href) return;\n\n if (\n _window.location.protocol !== anchor.protocol ||\n _window.location.hostname !== anchor.hostname ||\n _window.location.port !== anchor.port ||\n anchor.hasAttribute(\"data-router-ignore\") ||\n anchor.hasAttribute(\"download\") ||\n anchor.getAttribute(\"target\") === \"_blank\" ||\n /^[\\w-_]+:/.test(href)\n ) {\n return;\n }\n\n e.preventDefault();\n callback(href, anchor);\n }\n\n root.addEventListener(\"click\", handler as any);\n return () => root.removeEventListener(\"click\", handler as any);\n}\n\nexport function expandOptionalPaths(path: string): string[] {\n const parts = splitPath(path);\n const permutations: string[][] = [[]];\n\n for (const part of parts) {\n // Strictly enforces the inside style: {param?} or {#param?}\n const isOptional = part.endsWith(\"?}\");\n const cleanPart = isOptional ? part.replace(\"?\", \"\") : part;\n\n if (isOptional) {\n const withPart = permutations.map((p) => [...p, cleanPart]);\n permutations.push(...withPart);\n } else {\n for (const p of permutations) {\n p.push(cleanPart);\n }\n }\n }\n\n return permutations.map((p) => \"/\" + p.join(\"/\")).map((p) => (p === \"/\" ? p : p.replace(/\\/$/, \"\")));\n}\n\n/**\n * Replace route pattern param placeholders with real matched values.\n */\nexport function replaceParams(path: string, params: Record<string, string | number>) {\n for (const key in params) {\n const value = String(params[key]);\n path = path\n .replace(`{${key}}`, value)\n .replace(`{#${key}}`, value)\n .replace(`{${key}?}`, value) // Handle optional string param\n .replace(`{#${key}?}`, value); // Handle optional numeric param\n }\n\n // Remove any remaining unmatched optional parameters\n path = path.replace(/\\{#?[a-zA-Z0-9_]+\\?\\}/g, \"\");\n\n // Clean up any double slashes created by the removal\n path = path.replace(/\\/+/g, \"/\");\n\n // Strip trailing slash unless the entire path is just \"/\"\n if (path.length > 1 && path.endsWith(\"/\")) {\n path = path.slice(0, -1);\n }\n\n return path;\n}\n\nexport interface HistoryAdapter {\n getPath(): string;\n getSearch(): string;\n getKey(): string;\n getIndex(): number;\n push(url: string): void;\n replace(url: string): void;\n}\n\nexport function createHistoryAdapter(useHash: boolean): HistoryAdapter {\n let currentIndex = window.history.state?.index || 0;\n\n if (window.history.state?.index === undefined) {\n window.history.replaceState({ ...window.history.state, key: Date.now().toString(), index: currentIndex }, \"\");\n }\n\n const getPath = useHash ? () => window.location.hash.slice(1).split(\"?\")[0] || \"/\" : () => window.location.pathname;\n const getSearch = useHash\n ? () => {\n const hash = window.location.hash;\n const searchIndex = hash.indexOf(\"?\");\n return searchIndex !== -1 ? hash.slice(searchIndex) : \"\";\n }\n : () => window.location.search;\n\n const getKey = () => window.history.state?.key || \"root\";\n const getIndex = () => window.history.state?.index || 0;\n\n return {\n getPath,\n getSearch,\n getKey,\n getIndex,\n push: (url) => {\n currentIndex++;\n const prefix = useHash ? \"/#\" : \"\";\n window.history.pushState({ key: uniqueId(), index: currentIndex }, \"\", prefix + url);\n },\n replace: (url) => {\n const prefix = useHash ? \"/#\" : \"\";\n window.history.replaceState({ key: getKey(), index: currentIndex }, \"\", prefix + url);\n },\n };\n}\n","import { compose, getDebug, peek, type Context, type Getter, type Setter } from \"../core\";\nimport type { Router } from \"./types\";\nimport { mergeQueryParams, resolvePath, type HistoryAdapter, type Match } from \"./utils\";\n\nexport interface RouterStoreProps {\n currentMatch: Getter<Match>;\n setCurrentMatch: Setter<Match>;\n progress: Getter<number>;\n history: HistoryAdapter;\n updateRoute: () => void;\n guards: Set<() => boolean | Promise<boolean>>;\n}\n\nexport function RouterStore(\n this: Context,\n { currentMatch, setCurrentMatch, progress, history, updateRoute, guards }: RouterStoreProps,\n): Router {\n this.name = \"dolla:router\";\n const debug = getDebug(this);\n\n async function navigate(path: string, replace: boolean) {\n for (const guard of guards) {\n if (await guard()) return;\n }\n\n debug.info(`🗺️ navigating to '${path}'${replace ? \" (replace)\" : \"\"}`);\n\n const resolved = resolvePath(history.getPath(), path);\n replace ? history.replace(resolved) : history.push(resolved);\n updateRoute();\n }\n\n return {\n path: compose(() => currentMatch().path),\n pattern: compose(() => currentMatch().pattern),\n params: compose(() => currentMatch().params),\n query: compose(() => currentMatch().query),\n meta: compose(() => currentMatch().meta),\n progress: progress,\n\n setQuery(params) {\n const m = peek(currentMatch);\n const merged = mergeQueryParams(m.query, params, true);\n const query = Object.fromEntries(merged);\n\n setCurrentMatch({ ...m, query });\n\n const queryString = merged.size ? \"?\" + merged.toString() : \"\";\n history.replace(m.path + queryString);\n\n return query;\n },\n\n back: (steps = 1) => window.history.go(-steps),\n forward: (steps = 1) => window.history.go(steps),\n\n push: (path) => navigate(path, false),\n replace: (path) => navigate(path, true),\n\n block: (guard) => {\n guards.add(guard);\n return () => guards.delete(guard);\n },\n\n isActive(path: string, exact = false) {\n const target = path === \"/\" ? \"/\" : path.replace(/\\/$/, \"\");\n const targetSlash = target === \"/\" ? \"/\" : target + \"/\";\n\n return compose(() => {\n const current = currentMatch().path;\n const normalized = current === \"/\" ? \"/\" : current.replace(/\\/$/, \"\");\n\n if (exact) return normalized === target;\n\n // Ensure segment boundaries match (prevents /app matching /apple)\n return normalized === target || normalized.startsWith(targetSlash);\n });\n },\n };\n}\n","import { addStore, Context, createContext, onCleanup, onMount } from \"../core/context.js\";\nimport { DollaPlugin, getDebug, getRootElement } from \"../core/index.js\";\nimport { DynamicNode } from \"../core/markup/nodes/dynamic.js\";\nimport { ViewNode } from \"../core/markup/nodes/view.js\";\nimport type { MarkupNode } from \"../core/markup/types.js\";\nimport { addListener, createMarkup } from \"../core/markup/utils.js\";\nimport { batch, peek, createAtom } from \"../core/signals.js\";\nimport { DEBUG } from \"../core/symbols.js\";\nimport type { View } from \"../types.js\";\nimport { assert } from \"../utils.js\";\nimport { RouterStore } from \"./store.js\";\nimport type { ActiveLayer, LazyLoader, LazyView, RouterOptions } from \"./types.js\";\nimport {\n buildRouteTree,\n catchLinks,\n createHistoryAdapter,\n type Match,\n mergeQueryParams,\n replaceParams,\n resolveRoute,\n} from \"./utils.js\";\n\nconst ROUTER_ROOT_SLOT = Symbol();\n\n/**\n * Lazy loads a view when its route is first matched.\n *\n * @example\n * {\n * path: \"/users\",\n * view: lazy(() => import(\"./views/users.js\"))\n * }\n */\nexport function lazy(load: LazyLoader): LazyView {\n return { _lazy: true, load };\n}\n\nexport function createRouterPlugin(options: RouterOptions): DollaPlugin {\n return function (context) {\n if (\"scrollRestoration\" in window.history) {\n window.history.scrollRestoration = \"manual\";\n }\n\n const history = createHistoryAdapter(!!options.hash);\n const scrollCache = new Map<string, number>();\n let currentKey = history.getKey();\n\n const [currentMatch, setCurrentMatch] = createAtom<Match>({\n path: history.getPath(),\n pattern: \"\",\n params: {},\n query: Object.fromEntries(new URLSearchParams(history.getSearch())),\n meta: {},\n });\n\n const [progress, setProgress] = createAtom(0);\n const routeTree = buildRouteTree(options.routes);\n\n const guards = new Set<() => boolean | Promise<boolean>>();\n\n const routerContext = createContext(context);\n routerContext.name = \"dolla:router\";\n\n const console = getDebug(routerContext);\n const [rootSlot, setRootSlot] = createAtom<MarkupNode>();\n\n context[ROUTER_ROOT_SLOT] = rootSlot;\n\n const rootLayer: Partial<ActiveLayer> = {\n context,\n slot: rootSlot,\n setSlot: setRootSlot,\n };\n\n const activeLayers: ActiveLayer[] = [];\n\n /**\n * Run when the location changes. Diffs and mounts new routes and updates\n * the signals accordingly.\n */\n async function updateRoute(href?: string) {\n scrollCache.set(currentKey, window.scrollY);\n\n const path = href ?? history.getPath();\n const { match, journey } = await resolveRoute(routeTree, path);\n\n if (context[DEBUG]) {\n for (let i = 0; i < journey.length; i++) {\n const step = journey[i];\n const tag = `(update ${i + 1}/${journey.length})`;\n if (step.kind === \"match\") {\n console.info(`📍 ${tag} ${step.message}`);\n } else if (step.kind === \"redirect\") {\n console.info(`↩️ ${tag} ${step.message}`);\n } else {\n console.info(`💀 ${tag} ${step.message}`);\n }\n }\n }\n\n if (!match) throw new Error(`Failed to match route '${path}'`);\n\n const { layers, params } = match;\n const targetKeys: string[] = [];\n let branchIndex = 0;\n\n // Compute keys and find out where mounted layers diverge from matched layers\n for (let i = 0; i < layers.length; i++) {\n const key = `${layers[i].id}:${replaceParams(layers[i].pattern, params)}`;\n targetKeys.push(key);\n if (branchIndex === i && activeLayers[i]?.key === key) branchIndex++;\n }\n\n const tasks: Promise<void>[] = [];\n const preloadedData: any[] = []; // Offsets match loop index minus divIndex\n\n // Execute preloads and lazy component fetches\n for (let i = branchIndex; i < layers.length; i++) {\n const layer = layers[i];\n\n if (layer.preload) {\n tasks.push(\n Promise.resolve(layer.preload(match)).then((data) => {\n preloadedData[i - branchIndex] = data;\n }),\n );\n }\n\n const view = layer.view as LazyView;\n if (view._lazy) {\n tasks.push(\n view.load().then((mod) => {\n layer.view = (mod as any).default ?? mod; // Overwrite with loaded module\n }),\n );\n }\n }\n\n let caughtError: Error | null = null;\n let errorIndex = -1;\n\n // Track loading progress if there are async tasks\n if (tasks.length > 0) {\n setProgress(0.1);\n let completed = 0;\n const increment = 0.8 / tasks.length;\n\n tasks.forEach((p) => p.then(() => setProgress(0.1 + ++completed * increment)).catch(() => {}));\n\n try {\n await Promise.all(tasks);\n } catch (error) {\n setProgress(0);\n if (error instanceof RedirectError) return api.replace(error.redirectPath);\n\n caughtError = error instanceof Error ? error : new Error(String(error));\n errorIndex = branchIndex;\n }\n }\n\n // Merge query params and sync URL if redirect occurred\n const query = mergeQueryParams(peek(currentMatch).query, match.query, options.preserveQuery);\n const queryString = query.toString();\n const newUrl = match.path + (queryString ? `?${queryString}` : \"\");\n\n if (newUrl !== history.getPath() + history.getSearch()) {\n history.replace(newUrl);\n }\n\n // Batch state updates and DOM mutations\n batch(() => {\n setCurrentMatch({ ...match, query: Object.fromEntries(query) });\n\n if (branchIndex === layers.length && activeLayers.length === layers.length) return;\n\n // Fast truncate arrays and drop old DOM branches\n if (activeLayers[branchIndex]) {\n activeLayers[branchIndex].node.unmount();\n activeLayers.length = branchIndex;\n }\n\n // Mount new layers\n for (let i = branchIndex; i < layers.length; i++) {\n const layer = layers[i];\n const parent = activeLayers[i - 1] ?? rootLayer;\n const [slot, setSlot] = createAtom<MarkupNode>();\n\n let viewToMount = layer.view as View<any>;\n let propsToPass: any = {\n data: preloadedData[i - branchIndex],\n children: createMarkup(DynamicNode, { args: [slot] }),\n };\n\n // Handle Error Boundaries\n if (caughtError && i === errorIndex) {\n if (!layer.errorView) throw caughtError;\n viewToMount = layer.errorView;\n propsToPass = { error: caughtError };\n }\n\n const node = new ViewNode(parent.context!, viewToMount, propsToPass);\n parent.setSlot(node);\n\n activeLayers.push({\n id: layer.id,\n key: targetKeys[i],\n node,\n context: node.context,\n slot,\n setSlot,\n });\n\n if (caughtError && i === errorIndex) break;\n }\n });\n\n setProgress(0);\n\n requestAnimationFrame(() => {\n window.scrollTo(0, scrollCache.get(history.getKey()) ?? 0);\n currentKey = history.getKey();\n });\n }\n\n const api = addStore(context, RouterStore, {\n currentMatch,\n setCurrentMatch,\n progress,\n history,\n updateRoute,\n guards,\n });\n\n onMount(context, () => {\n let isReverting = false;\n let isReplaying = false;\n let lastIndex = history.getIndex();\n\n const removePop = addListener(window, \"popstate\", async () => {\n // If this popstate is the result of us reverting the URL, ignore it.\n if (isReverting) {\n isReverting = false;\n return;\n }\n\n // If this popstate is the result of us replaying an allowed navigation, accept it.\n if (isReplaying) {\n isReplaying = false;\n lastIndex = history.getIndex();\n updateRoute();\n return;\n }\n\n const newIndex = history.getIndex();\n const delta = lastIndex - newIndex; // Positive if user clicked Back\n\n // If guards exist, revert synchronously first\n if (guards.size > 0) {\n isReverting = true;\n window.history.go(delta); // Restores the URL immediately\n\n // Run guards while the URL is back in its original state\n let blocked = false;\n for (const guard of guards) {\n if (await guard()) {\n blocked = true;\n break;\n }\n }\n\n // If guards passed, replay the intended navigation\n if (!blocked) {\n isReplaying = true;\n window.history.go(-delta);\n }\n return;\n }\n\n // Normal flow (no guards)\n lastIndex = newIndex;\n updateRoute();\n });\n\n // Block tab closure/reload if guards exist\n const removeUnload = addListener(window, \"beforeunload\", (e: BeforeUnloadEvent) => {\n if (guards.size > 0) {\n e.preventDefault();\n e.returnValue = \"\"; // Triggers the native browser warning dialog\n }\n });\n\n const removeClick = catchLinks(getRootElement(context), api.push);\n\n onCleanup(context, () => {\n removePop();\n removeUnload();\n removeClick();\n });\n\n updateRoute();\n });\n };\n}\n\n/**\n * Displays the router's content.\n */\nexport function Outlet(this: Context) {\n this.name = \"dolla:router\";\n\n const rootSlot = this[ROUTER_ROOT_SLOT];\n assert(rootSlot != null, \"Router plugin not found on root.\");\n\n return new DynamicNode(this, rootSlot);\n}\n\nexport class RedirectError extends Error {\n constructor(public redirectPath: string) {\n super(`Redirecting to ${redirectPath}`);\n this.name = \"RedirectError\";\n }\n}\n","import { Context, getStore } from \"../core\";\nimport { RouterStore } from \"./store\";\n\nexport { createRouterPlugin, lazy, Outlet, RedirectError } from \"./router\";\nexport type { RouterOptions } from \"./types\";\n\nexport function getRouter(context: Context) {\n return getStore(context, RouterStore);\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
//#region src/utils.ts
|
|
2
|
+
var e = 0;
|
|
3
|
+
function t() {
|
|
4
|
+
return (e++).toString(36);
|
|
5
|
+
}
|
|
6
|
+
function n(e, t) {
|
|
7
|
+
let n = {};
|
|
8
|
+
for (let r in t) e.includes(r) || (n[r] = t[r]);
|
|
9
|
+
return n;
|
|
10
|
+
}
|
|
11
|
+
function r(e, t) {
|
|
12
|
+
if (!e) throw TypeError(t);
|
|
13
|
+
}
|
|
14
|
+
function i(e) {
|
|
15
|
+
return Array.isArray(e);
|
|
16
|
+
}
|
|
17
|
+
function a(e) {
|
|
18
|
+
return typeof e == "string";
|
|
19
|
+
}
|
|
20
|
+
function o(e) {
|
|
21
|
+
return typeof e == "function" && !s(e);
|
|
22
|
+
}
|
|
23
|
+
function s(e) {
|
|
24
|
+
return /^\s*class\s+/.test(String(e));
|
|
25
|
+
}
|
|
26
|
+
function c(e) {
|
|
27
|
+
return typeof e == "number" && !isNaN(e);
|
|
28
|
+
}
|
|
29
|
+
function l(e) {
|
|
30
|
+
return typeof e == "object" && !!e && !i(e);
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
33
|
+
//#region src/core/signals.ts
|
|
34
|
+
var u = /* @__PURE__ */ function(e) {
|
|
35
|
+
return e[e.None = 0] = "None", e[e.Mutable = 1] = "Mutable", e[e.Watching = 2] = "Watching", e[e.RecursedCheck = 4] = "RecursedCheck", e[e.Recursed = 8] = "Recursed", e[e.Dirty = 16] = "Dirty", e[e.Pending = 32] = "Pending", e;
|
|
36
|
+
}(u || {}), d = 0, f = 0, p = 0, m = 0, h, g = [];
|
|
37
|
+
function _(e, t, n) {
|
|
38
|
+
let r = t._depsTail;
|
|
39
|
+
if (r !== void 0 && r._dep === e) return;
|
|
40
|
+
let i = r === void 0 ? t._deps : r._nextDep;
|
|
41
|
+
if (i !== void 0 && i._dep === e) {
|
|
42
|
+
i._version = n, t._depsTail = i;
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
let a = e._subsTail;
|
|
46
|
+
if (a !== void 0 && a._version === n && a._sub === t) return;
|
|
47
|
+
let o = t._depsTail = e._subsTail = {
|
|
48
|
+
_version: n,
|
|
49
|
+
_dep: e,
|
|
50
|
+
_sub: t,
|
|
51
|
+
_prevDep: r,
|
|
52
|
+
_nextDep: i,
|
|
53
|
+
_prevSub: a,
|
|
54
|
+
_nextSub: void 0
|
|
55
|
+
};
|
|
56
|
+
i !== void 0 && (i._prevDep = o), r === void 0 ? t._deps = o : r._nextDep = o, a === void 0 ? e._subs = o : a._nextSub = o;
|
|
57
|
+
}
|
|
58
|
+
function v(e) {
|
|
59
|
+
e._flags & u.Mutable ? e._depsTail !== void 0 && (e._depsTail = void 0, e._flags = u.Mutable | u.Dirty, j(e)) : L.call(e);
|
|
60
|
+
}
|
|
61
|
+
function y(e, t = e._sub) {
|
|
62
|
+
let n = e._dep, r = e._prevDep, i = e._nextDep, a = e._nextSub, o = e._prevSub;
|
|
63
|
+
return i === void 0 ? t._depsTail = r : i._prevDep = r, r === void 0 ? t._deps = i : r._nextDep = i, a === void 0 ? n._subsTail = o : a._prevSub = o, o === void 0 ? (n._subs = a) === void 0 && v(n) : o._nextSub = a, i;
|
|
64
|
+
}
|
|
65
|
+
function b(e) {
|
|
66
|
+
let t = m, n = t;
|
|
67
|
+
do
|
|
68
|
+
if (g[t++] = e, e._flags &= ~u.Watching, e = e._subs?._sub, e === void 0 || !(e._flags & u.Watching)) break;
|
|
69
|
+
while (!0);
|
|
70
|
+
for (m = t; n < --t;) {
|
|
71
|
+
let e = g[n];
|
|
72
|
+
g[n++] = g[t], g[t] = e;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function x(e) {
|
|
76
|
+
return e._depsTail === void 0 ? O(e) : D(e);
|
|
77
|
+
}
|
|
78
|
+
function S(e) {
|
|
79
|
+
let t = e._nextSub, n;
|
|
80
|
+
top: do {
|
|
81
|
+
let r = e._sub, i = r._flags;
|
|
82
|
+
if (i & (u.RecursedCheck | u.Recursed | u.Dirty | u.Pending) ? i & (u.RecursedCheck | u.Recursed) ? i & u.RecursedCheck ? !(i & (u.Dirty | u.Pending)) && T(e, r) ? (r._flags = i | (u.Recursed | u.Pending), i &= u.Mutable) : i = u.None : r._flags = i & ~u.Recursed | u.Pending : i = u.None : r._flags = i | u.Pending, i & u.Watching && b(r), i & u.Mutable) {
|
|
83
|
+
let i = r._subs;
|
|
84
|
+
if (i !== void 0) {
|
|
85
|
+
let r = (e = i)._nextSub;
|
|
86
|
+
r !== void 0 && (n = {
|
|
87
|
+
_value: t,
|
|
88
|
+
_prev: n
|
|
89
|
+
}, t = r);
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
if ((e = t) !== void 0) {
|
|
94
|
+
t = e._nextSub;
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
for (; n !== void 0;) if (e = n._value, n = n._prev, e !== void 0) {
|
|
98
|
+
t = e._nextSub;
|
|
99
|
+
continue top;
|
|
100
|
+
}
|
|
101
|
+
break;
|
|
102
|
+
} while (!0);
|
|
103
|
+
}
|
|
104
|
+
function C(e, t) {
|
|
105
|
+
let n, r = 0, i = !1;
|
|
106
|
+
top: do {
|
|
107
|
+
let a = e._dep, o = a._flags;
|
|
108
|
+
if (t._flags & u.Dirty) i = !0;
|
|
109
|
+
else if ((o & (u.Mutable | u.Dirty)) === (u.Mutable | u.Dirty)) {
|
|
110
|
+
if (x(a)) {
|
|
111
|
+
let e = a._subs;
|
|
112
|
+
e._nextSub !== void 0 && w(e), i = !0;
|
|
113
|
+
}
|
|
114
|
+
} else if ((o & (u.Mutable | u.Pending)) === (u.Mutable | u.Pending)) {
|
|
115
|
+
(e._nextSub !== void 0 || e._prevSub !== void 0) && (n = {
|
|
116
|
+
_value: e,
|
|
117
|
+
_prev: n
|
|
118
|
+
}), e = a._deps, t = a, ++r;
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
if (!i) {
|
|
122
|
+
let t = e._nextDep;
|
|
123
|
+
if (t !== void 0) {
|
|
124
|
+
e = t;
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
for (; r--;) {
|
|
129
|
+
let r = t._subs, a = r._nextSub !== void 0;
|
|
130
|
+
if (a ? (e = n._value, n = n._prev) : e = r, i) {
|
|
131
|
+
if (x(t)) {
|
|
132
|
+
a && w(r), t = e._sub;
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
i = !1;
|
|
136
|
+
} else t._flags &= ~u.Pending;
|
|
137
|
+
t = e._sub;
|
|
138
|
+
let o = e._nextDep;
|
|
139
|
+
if (o !== void 0) {
|
|
140
|
+
e = o;
|
|
141
|
+
continue top;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return i;
|
|
145
|
+
} while (!0);
|
|
146
|
+
}
|
|
147
|
+
function w(e) {
|
|
148
|
+
do {
|
|
149
|
+
let t = e._sub, n = t._flags;
|
|
150
|
+
(n & (u.Pending | u.Dirty)) === u.Pending && (t._flags = n | u.Dirty, (n & (u.Watching | u.RecursedCheck)) === u.Watching && b(t));
|
|
151
|
+
} while ((e = e._nextSub) !== void 0);
|
|
152
|
+
}
|
|
153
|
+
function T(e, t) {
|
|
154
|
+
let n = t._depsTail;
|
|
155
|
+
for (; n !== void 0;) {
|
|
156
|
+
if (n === e) return !0;
|
|
157
|
+
n = n._prevDep;
|
|
158
|
+
}
|
|
159
|
+
return !1;
|
|
160
|
+
}
|
|
161
|
+
function E(e) {
|
|
162
|
+
let t = h;
|
|
163
|
+
return h = e, t;
|
|
164
|
+
}
|
|
165
|
+
function D(e) {
|
|
166
|
+
++d, e._depsTail = void 0, e._flags = u.Mutable | u.RecursedCheck;
|
|
167
|
+
let t = E(e);
|
|
168
|
+
try {
|
|
169
|
+
let t = e._value;
|
|
170
|
+
return t !== (e._value = e._getter(t));
|
|
171
|
+
} finally {
|
|
172
|
+
h = t, e._flags &= ~u.RecursedCheck, j(e);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
function O(e) {
|
|
176
|
+
return e._flags = u.Mutable, e._currentValue !== (e._currentValue = e._pendingValue);
|
|
177
|
+
}
|
|
178
|
+
function k(e) {
|
|
179
|
+
let t = e._flags;
|
|
180
|
+
if (t & u.Dirty || t & u.Pending && C(e._deps, e)) {
|
|
181
|
+
++d, e._depsTail = void 0, e._flags = u.Watching | u.RecursedCheck;
|
|
182
|
+
let t = E(e);
|
|
183
|
+
try {
|
|
184
|
+
e._cleanup?.(), e._cleanup = void 0;
|
|
185
|
+
let t = e._fn();
|
|
186
|
+
o(t) && (e._cleanup = t);
|
|
187
|
+
} finally {
|
|
188
|
+
h = t, e._flags &= ~u.RecursedCheck, j(e);
|
|
189
|
+
}
|
|
190
|
+
} else e._flags = u.Watching;
|
|
191
|
+
}
|
|
192
|
+
function A() {
|
|
193
|
+
try {
|
|
194
|
+
for (; p < m;) {
|
|
195
|
+
let e = g[p];
|
|
196
|
+
g[p++] = void 0, k(e);
|
|
197
|
+
}
|
|
198
|
+
} finally {
|
|
199
|
+
for (; p < m;) {
|
|
200
|
+
let e = g[p];
|
|
201
|
+
g[p++] = void 0, e._flags |= u.Watching | u.Recursed;
|
|
202
|
+
}
|
|
203
|
+
p = 0, m = 0;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
function j(e) {
|
|
207
|
+
let t = e._depsTail, n = t === void 0 ? e._deps : t._nextDep;
|
|
208
|
+
for (; n !== void 0;) n = y(n, e);
|
|
209
|
+
}
|
|
210
|
+
function M(e, t) {
|
|
211
|
+
return o(e) ? H(() => e(t)) : e;
|
|
212
|
+
}
|
|
213
|
+
function N() {
|
|
214
|
+
let e = this._flags;
|
|
215
|
+
if (e & u.Dirty || e & u.Pending && (C(this._deps, this) || (this._flags = e & ~u.Pending, !1))) {
|
|
216
|
+
if (D(this)) {
|
|
217
|
+
let e = this._subs;
|
|
218
|
+
e !== void 0 && w(e);
|
|
219
|
+
}
|
|
220
|
+
} else if (!e) {
|
|
221
|
+
this._flags = u.Mutable | u.RecursedCheck;
|
|
222
|
+
let e = E(this);
|
|
223
|
+
try {
|
|
224
|
+
this._value = V(this._getter());
|
|
225
|
+
} finally {
|
|
226
|
+
h = e, this._flags &= ~u.RecursedCheck;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
let t = h;
|
|
230
|
+
return t !== void 0 && _(this, t, d), this._value;
|
|
231
|
+
}
|
|
232
|
+
function P(e) {
|
|
233
|
+
let t = M(e, this._value);
|
|
234
|
+
if (this._value !== t) {
|
|
235
|
+
this._value = t, this._flags &= ~(u.Dirty | u.Pending);
|
|
236
|
+
let e = this._subs;
|
|
237
|
+
for (; e !== void 0;) {
|
|
238
|
+
let t = e._sub, n = t._flags;
|
|
239
|
+
(n & (u.Dirty | u.Pending)) === 0 && (t._flags = n | u.Dirty, b(t)), e = e._nextSub;
|
|
240
|
+
}
|
|
241
|
+
f || A();
|
|
242
|
+
}
|
|
243
|
+
return t;
|
|
244
|
+
}
|
|
245
|
+
function F() {
|
|
246
|
+
if (this._flags & u.Dirty && O(this)) {
|
|
247
|
+
let e = this._subs;
|
|
248
|
+
e !== void 0 && w(e);
|
|
249
|
+
}
|
|
250
|
+
let e = h;
|
|
251
|
+
for (; e !== void 0;) {
|
|
252
|
+
if (e._flags & (u.Mutable | u.Watching)) {
|
|
253
|
+
_(this, e, d);
|
|
254
|
+
break;
|
|
255
|
+
}
|
|
256
|
+
e = e._subs?._sub;
|
|
257
|
+
}
|
|
258
|
+
return this._currentValue;
|
|
259
|
+
}
|
|
260
|
+
function I(e) {
|
|
261
|
+
let t = M(e, this._pendingValue);
|
|
262
|
+
if (this._pendingValue !== (this._pendingValue = t)) {
|
|
263
|
+
this._flags = u.Mutable | u.Dirty;
|
|
264
|
+
let e = this._subs;
|
|
265
|
+
e !== void 0 && (S(e), f || A());
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
function L() {
|
|
269
|
+
this._depsTail = void 0, this._flags = u.None, j(this);
|
|
270
|
+
let e = this._subs;
|
|
271
|
+
e !== void 0 && y(e), this._cleanup?.(), this._cleanup = void 0;
|
|
272
|
+
}
|
|
273
|
+
function R(e) {
|
|
274
|
+
if (o(e)) {
|
|
275
|
+
let t = {
|
|
276
|
+
_value: void 0,
|
|
277
|
+
_subs: void 0,
|
|
278
|
+
_subsTail: void 0,
|
|
279
|
+
_deps: void 0,
|
|
280
|
+
_depsTail: void 0,
|
|
281
|
+
_flags: u.None,
|
|
282
|
+
_getter: e
|
|
283
|
+
};
|
|
284
|
+
return [N.bind(t), P.bind(t)];
|
|
285
|
+
} else {
|
|
286
|
+
let t = {
|
|
287
|
+
_currentValue: e,
|
|
288
|
+
_pendingValue: e,
|
|
289
|
+
_subs: void 0,
|
|
290
|
+
_subsTail: void 0,
|
|
291
|
+
_flags: u.Mutable
|
|
292
|
+
};
|
|
293
|
+
return [F.bind(t), I.bind(t)];
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
function z(e) {
|
|
297
|
+
return N.bind({
|
|
298
|
+
_value: void 0,
|
|
299
|
+
_subs: void 0,
|
|
300
|
+
_subsTail: void 0,
|
|
301
|
+
_deps: void 0,
|
|
302
|
+
_depsTail: void 0,
|
|
303
|
+
_flags: u.None,
|
|
304
|
+
_getter: e
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
function B(e) {
|
|
308
|
+
let t = {
|
|
309
|
+
_fn: e,
|
|
310
|
+
_cleanup: void 0,
|
|
311
|
+
_subs: void 0,
|
|
312
|
+
_subsTail: void 0,
|
|
313
|
+
_deps: void 0,
|
|
314
|
+
_depsTail: void 0,
|
|
315
|
+
_flags: u.Watching | u.RecursedCheck
|
|
316
|
+
}, n = E(t);
|
|
317
|
+
n !== void 0 && _(t, n, 0);
|
|
318
|
+
try {
|
|
319
|
+
let e = t._fn();
|
|
320
|
+
o(e) && (t._cleanup = e);
|
|
321
|
+
} finally {
|
|
322
|
+
h = n, t._flags &= ~u.RecursedCheck;
|
|
323
|
+
}
|
|
324
|
+
return L.bind(t);
|
|
325
|
+
}
|
|
326
|
+
function V(e) {
|
|
327
|
+
return o(e) ? e() : e;
|
|
328
|
+
}
|
|
329
|
+
function H(e) {
|
|
330
|
+
let t = E(void 0);
|
|
331
|
+
try {
|
|
332
|
+
return V(e);
|
|
333
|
+
} finally {
|
|
334
|
+
E(t);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
function U(e) {
|
|
338
|
+
++f;
|
|
339
|
+
try {
|
|
340
|
+
e();
|
|
341
|
+
} finally {
|
|
342
|
+
--f || A();
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
function W(e, t) {
|
|
346
|
+
return B(() => {
|
|
347
|
+
let n = e();
|
|
348
|
+
H(() => t(n));
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
//#endregion
|
|
352
|
+
export { H as a, r as c, c as d, l as f, t as h, B as i, i as l, n as m, z as n, W as o, a as p, R as r, V as s, U as t, o as u };
|
|
353
|
+
|
|
354
|
+
//# sourceMappingURL=signals-CMJPGr_M.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signals-CMJPGr_M.js","names":[],"sources":["../src/utils.ts","../src/core/signals.ts"],"sourcesContent":["/*=============================*\\\n|| ID Generator ||\n\\*=============================*/\n\nlet lastId = 0;\nexport function uniqueId() {\n return (lastId++).toString(36);\n}\n\n/*=============================*\\\n|| Object Utils ||\n\\*=============================*/\n\n/**\n * Returns a new object without the specified keys.\n * If called without object, returns a function that takes an object\n * and returns a version with the original keys omitted.\n *\n * @param keys - An array of keys to omit.\n * @param object - An object to clone without the omitted keys.\n */\nexport function omit<O extends Record<any, any>>(keys: (keyof O)[], object: O): Record<any, any> {\n const newObject: Record<any, any> = {};\n\n for (const key in object) {\n if (!keys.includes(key)) {\n newObject[key] = object[key];\n }\n }\n\n return newObject;\n}\n\n/*=============================*\\\n|| Type Checking ||\n\\*=============================*/\n\n/**\n * Throws a TypeError unless `condition` is truthy.\n *\n * @param value - Value whose truthiness is in question.\n * @param errorMessage - Optional message for the thrown TypeError.\n */\nexport function assert<T = any>(value: T, errorMessage: string): asserts value is NonNullable<T> {\n if (!value) throw new TypeError(errorMessage);\n}\n\n/**\n * Returns true if `value` is an array.\n */\nexport function isArray(value: unknown): value is Array<unknown> {\n return Array.isArray(value);\n}\n\n/**\n * Returns true when `value` is an array and `check` returns true for every item.\n *\n * @param check - Function to check items against.\n * @param value - A possible array.\n */\nexport function isArrayOf<T>(check: (item: unknown) => boolean, value: unknown): value is T[];\nexport function isArrayOf<T>(check: (item: unknown) => boolean): (value: unknown) => value is T[];\n\nexport function isArrayOf<T>(check: (item: unknown) => boolean, value?: unknown) {\n if (value) {\n return isArray(value) && value.every((item) => check(item));\n } else {\n return (value: unknown) => isArrayOf<T>(check, value);\n }\n}\n\n/**\n * Returns true if `value` is a string.\n */\nexport function isString(value: unknown): value is string {\n return typeof value === \"string\";\n}\n\n/**\n * Returns true if `value` is a function (but not a class).\n */\nexport function isFunction<T = (...args: unknown[]) => unknown>(value: unknown): value is T {\n return typeof value === \"function\" && !isClass(value);\n}\n\nexport function isClass(value: unknown) {\n return /^\\s*class\\s+/.test(String(value));\n}\n\n/**\n * Returns true if `value` is a number.\n */\nexport function isNumber(value: unknown): value is number {\n return typeof value === \"number\" && !isNaN(value);\n}\n\n/**\n * Returns `true` if `value` is an instance of `constructor`.\n *\n * @param constructor - The constructor `value` must be an instance of.\n * @param value - A value that may be an instance of `constructor`.\n */\nexport function isInstanceOf<T extends Function>(constructor: T, value: unknown): value is T;\nexport function isInstanceOf<T extends Function>(constructor: T): (value: unknown) => value is T;\n\nexport function isInstanceOf<T extends Function>(constructor: T, value?: unknown) {\n if (value) {\n return value instanceof constructor;\n } else {\n return (value: unknown) => isInstanceOf(constructor, value);\n }\n}\n\n/**\n * Returns true if `value` is a JavaScript Promise.\n */\nexport function isPromise<T = unknown>(value: unknown): value is Promise<T> {\n return value instanceof Promise;\n}\n\n/**\n * Returns true if `value` is a plain JavaScript object.\n */\nexport function isObject<T = Record<string | number | symbol, unknown>>(value: unknown): value is T {\n return value != null && typeof value === \"object\" && !isArray(value);\n}\n","import { isFunction } from \"../utils.js\";\n\ninterface ReactiveNode {\n _deps?: Link;\n _depsTail?: Link;\n _subs?: Link;\n _subsTail?: Link;\n _flags: ReactiveFlags;\n}\n\ninterface EffectNode extends ReactiveNode {\n _fn(): void | (() => void);\n _cleanup?: () => void;\n}\n\ninterface ComputedNode<T = any> extends ReactiveNode {\n _value: T | undefined;\n _getter: (previousValue?: T) => T;\n}\n\ninterface ValueNode<T = any> extends ReactiveNode {\n _currentValue: T;\n _pendingValue: T;\n}\n\ninterface Link {\n _version: number;\n _dep: ReactiveNode;\n _sub: ReactiveNode;\n _prevSub: Link | undefined;\n _nextSub: Link | undefined;\n _prevDep: Link | undefined;\n _nextDep: Link | undefined;\n}\n\ninterface Stack<T> {\n _value: T;\n _prev: Stack<T> | undefined;\n}\n\n/*==================================*\\\n|| Signal Internals ||\n\\*==================================*/\n\nconst enum ReactiveFlags {\n None = 0,\n Mutable = 1,\n Watching = 2,\n RecursedCheck = 4,\n Recursed = 8,\n Dirty = 16,\n Pending = 32,\n}\n\nlet cycle = 0;\nlet batchDepth = 0;\nlet notifyIndex = 0;\nlet queuedLength = 0;\nlet activeSub: ReactiveNode | undefined;\n\nconst queued: (EffectNode | undefined)[] = [];\n\nfunction link(dep: ReactiveNode, sub: ReactiveNode, version: number): void {\n const prevDep = sub._depsTail;\n if (prevDep !== undefined && prevDep._dep === dep) {\n return;\n }\n const nextDep = prevDep !== undefined ? prevDep._nextDep : sub._deps;\n if (nextDep !== undefined && nextDep._dep === dep) {\n nextDep._version = version;\n sub._depsTail = nextDep;\n return;\n }\n const prevSub = dep._subsTail;\n if (prevSub !== undefined && prevSub._version === version && prevSub._sub === sub) {\n return;\n }\n const newLink =\n (sub._depsTail =\n dep._subsTail =\n {\n _version: version,\n _dep: dep,\n _sub: sub,\n _prevDep: prevDep,\n _nextDep: nextDep,\n _prevSub: prevSub,\n _nextSub: undefined,\n });\n if (nextDep !== undefined) {\n nextDep._prevDep = newLink;\n }\n if (prevDep !== undefined) {\n prevDep._nextDep = newLink;\n } else {\n sub._deps = newLink;\n }\n if (prevSub !== undefined) {\n prevSub._nextSub = newLink;\n } else {\n dep._subs = newLink;\n }\n}\n\nfunction unwatched(node: ReactiveNode): void {\n if (!(node._flags & ReactiveFlags.Mutable)) {\n effectCleanup.call(node);\n } else if (node._depsTail !== undefined) {\n node._depsTail = undefined;\n node._flags = ReactiveFlags.Mutable | ReactiveFlags.Dirty;\n purgeDeps(node);\n }\n}\n\nfunction unlink(link: Link, sub = link._sub): Link | undefined {\n const dep = link._dep;\n const prevDep = link._prevDep;\n const nextDep = link._nextDep;\n const nextSub = link._nextSub;\n const prevSub = link._prevSub;\n if (nextDep !== undefined) {\n nextDep._prevDep = prevDep;\n } else {\n sub._depsTail = prevDep;\n }\n if (prevDep !== undefined) {\n prevDep._nextDep = nextDep;\n } else {\n sub._deps = nextDep;\n }\n if (nextSub !== undefined) {\n nextSub._prevSub = prevSub;\n } else {\n dep._subsTail = prevSub;\n }\n if (prevSub !== undefined) {\n prevSub._nextSub = nextSub;\n } else if ((dep._subs = nextSub) === undefined) {\n unwatched(dep);\n }\n return nextDep;\n}\n\nfunction notify(effect: EffectNode): void {\n let insertIndex = queuedLength;\n let firstInsertedIndex = insertIndex;\n\n do {\n queued[insertIndex++] = effect;\n effect._flags &= ~ReactiveFlags.Watching;\n effect = effect._subs?._sub as EffectNode;\n if (effect === undefined || !(effect._flags & ReactiveFlags.Watching)) {\n break;\n }\n } while (true);\n\n queuedLength = insertIndex;\n\n while (firstInsertedIndex < --insertIndex) {\n const left = queued[firstInsertedIndex];\n queued[firstInsertedIndex++] = queued[insertIndex];\n queued[insertIndex] = left;\n }\n}\n\nfunction update(node: ReactiveNode): boolean {\n if (node._depsTail !== undefined) {\n return updateComputed(node as ComputedNode);\n } else {\n return updateValue(node as ValueNode);\n }\n}\n\nfunction propagate(link: Link): void {\n let next = link._nextSub;\n let stack: Stack<Link | undefined> | undefined;\n\n top: do {\n const sub = link._sub;\n let flags = sub._flags;\n\n if (\n !(flags & (ReactiveFlags.RecursedCheck | ReactiveFlags.Recursed | ReactiveFlags.Dirty | ReactiveFlags.Pending))\n ) {\n sub._flags = flags | ReactiveFlags.Pending;\n } else if (!(flags & (ReactiveFlags.RecursedCheck | ReactiveFlags.Recursed))) {\n flags = ReactiveFlags.None;\n } else if (!(flags & ReactiveFlags.RecursedCheck)) {\n sub._flags = (flags & ~ReactiveFlags.Recursed) | ReactiveFlags.Pending;\n } else if (!(flags & (ReactiveFlags.Dirty | ReactiveFlags.Pending)) && isValidLink(link, sub)) {\n sub._flags = flags | (ReactiveFlags.Recursed | ReactiveFlags.Pending);\n flags &= ReactiveFlags.Mutable;\n } else {\n flags = ReactiveFlags.None;\n }\n\n if (flags & ReactiveFlags.Watching) {\n notify(sub as EffectNode);\n }\n\n if (flags & ReactiveFlags.Mutable) {\n const subSubs = sub._subs;\n if (subSubs !== undefined) {\n const nextSub = (link = subSubs)._nextSub;\n if (nextSub !== undefined) {\n stack = { _value: next, _prev: stack };\n next = nextSub;\n }\n continue;\n }\n }\n\n if ((link = next!) !== undefined) {\n next = link._nextSub;\n continue;\n }\n\n while (stack !== undefined) {\n link = stack._value!;\n stack = stack._prev;\n if (link !== undefined) {\n next = link._nextSub;\n continue top;\n }\n }\n\n break;\n } while (true);\n}\n\nfunction checkDirty(link: Link, sub: ReactiveNode): boolean {\n let stack: Stack<Link> | undefined;\n let checkDepth = 0;\n let dirty = false;\n\n top: do {\n const dep = link._dep;\n const flags = dep._flags;\n\n if (sub._flags & ReactiveFlags.Dirty) {\n dirty = true;\n } else if (\n (flags & (ReactiveFlags.Mutable | ReactiveFlags.Dirty)) ===\n (ReactiveFlags.Mutable | ReactiveFlags.Dirty)\n ) {\n if (update(dep)) {\n const subs = dep._subs!;\n if (subs._nextSub !== undefined) {\n shallowPropagate(subs);\n }\n dirty = true;\n }\n } else if (\n (flags & (ReactiveFlags.Mutable | ReactiveFlags.Pending)) ===\n (ReactiveFlags.Mutable | ReactiveFlags.Pending)\n ) {\n if (link._nextSub !== undefined || link._prevSub !== undefined) {\n stack = { _value: link, _prev: stack };\n }\n link = dep._deps!;\n sub = dep;\n ++checkDepth;\n continue;\n }\n\n if (!dirty) {\n const nextDep = link._nextDep;\n if (nextDep !== undefined) {\n link = nextDep;\n continue;\n }\n }\n\n while (checkDepth--) {\n const firstSub = sub._subs!;\n const hasMultipleSubs = firstSub._nextSub !== undefined;\n if (hasMultipleSubs) {\n link = stack!._value;\n stack = stack!._prev;\n } else {\n link = firstSub;\n }\n if (dirty) {\n if (update(sub)) {\n if (hasMultipleSubs) {\n shallowPropagate(firstSub);\n }\n sub = link._sub;\n continue;\n }\n dirty = false;\n } else {\n sub._flags &= ~ReactiveFlags.Pending;\n }\n sub = link._sub;\n const nextDep = link._nextDep;\n if (nextDep !== undefined) {\n link = nextDep;\n continue top;\n }\n }\n\n return dirty;\n } while (true);\n}\n\nfunction shallowPropagate(link: Link): void {\n do {\n const sub = link._sub;\n const flags = sub._flags;\n if ((flags & (ReactiveFlags.Pending | ReactiveFlags.Dirty)) === ReactiveFlags.Pending) {\n sub._flags = flags | ReactiveFlags.Dirty;\n if ((flags & (ReactiveFlags.Watching | ReactiveFlags.RecursedCheck)) === ReactiveFlags.Watching) {\n notify(sub as EffectNode);\n }\n }\n } while ((link = link._nextSub!) !== undefined);\n}\n\nfunction isValidLink(checkLink: Link, sub: ReactiveNode): boolean {\n let link = sub._depsTail;\n while (link !== undefined) {\n if (link === checkLink) {\n return true;\n }\n link = link._prevDep;\n }\n return false;\n}\n\nfunction setActiveSub(sub?: ReactiveNode) {\n const prevSub = activeSub;\n activeSub = sub;\n return prevSub;\n}\n\nfunction updateComputed(c: ComputedNode): boolean {\n ++cycle;\n c._depsTail = undefined;\n c._flags = ReactiveFlags.Mutable | ReactiveFlags.RecursedCheck;\n const prevSub = setActiveSub(c);\n try {\n const oldValue = c._value;\n return oldValue !== (c._value = c._getter(oldValue));\n } finally {\n activeSub = prevSub;\n c._flags &= ~ReactiveFlags.RecursedCheck;\n purgeDeps(c);\n }\n}\n\nfunction updateValue(v: ValueNode): boolean {\n v._flags = ReactiveFlags.Mutable;\n return v._currentValue !== (v._currentValue = v._pendingValue);\n}\n\nfunction run(e: EffectNode): void {\n const flags = e._flags;\n if (flags & ReactiveFlags.Dirty || (flags & ReactiveFlags.Pending && checkDirty(e._deps!, e))) {\n ++cycle;\n e._depsTail = undefined;\n e._flags = ReactiveFlags.Watching | ReactiveFlags.RecursedCheck;\n const prevSub = setActiveSub(e);\n try {\n e._cleanup?.();\n e._cleanup = undefined;\n const result = e._fn();\n if (isFunction(result)) e._cleanup = result;\n } finally {\n activeSub = prevSub;\n e._flags &= ~ReactiveFlags.RecursedCheck;\n purgeDeps(e);\n }\n } else {\n e._flags = ReactiveFlags.Watching;\n }\n}\n\nfunction flush(): void {\n try {\n while (notifyIndex < queuedLength) {\n const effect = queued[notifyIndex]!;\n queued[notifyIndex++] = undefined;\n run(effect);\n }\n } finally {\n while (notifyIndex < queuedLength) {\n const effect = queued[notifyIndex]!;\n queued[notifyIndex++] = undefined;\n effect._flags |= ReactiveFlags.Watching | ReactiveFlags.Recursed;\n }\n notifyIndex = 0;\n queuedLength = 0;\n }\n}\n\nfunction purgeDeps(sub: ReactiveNode) {\n const depsTail = sub._depsTail;\n let dep = depsTail !== undefined ? depsTail._nextDep : sub._deps;\n while (dep !== undefined) {\n dep = unlink(dep, sub);\n }\n}\n\n/*==================================*\\\n|| API Implementation ||\n\\*==================================*/\n\nfunction resolveValue<T>(next: SetterAction<T>, current: T): T {\n if (isFunction(next)) return peek(() => next(current)) as T;\n return next as T;\n}\n\nfunction computedGetter(this: ComputedNode) {\n const flags = this._flags;\n if (\n flags & ReactiveFlags.Dirty ||\n (flags & ReactiveFlags.Pending &&\n (checkDirty(this._deps!, this) || ((this._flags = flags & ~ReactiveFlags.Pending), false)))\n ) {\n if (updateComputed(this)) {\n const subs = this._subs;\n if (subs !== undefined) {\n shallowPropagate(subs);\n }\n }\n } else if (!flags) {\n this._flags = ReactiveFlags.Mutable | ReactiveFlags.RecursedCheck;\n const prevSub = setActiveSub(this);\n try {\n this._value = unwrap(this._getter());\n } finally {\n activeSub = prevSub;\n this._flags &= ~ReactiveFlags.RecursedCheck;\n }\n }\n const sub = activeSub;\n if (sub !== undefined) {\n link(this, sub, cycle);\n }\n return this._value!;\n}\n\nfunction computedSetter(this: ComputedNode, next: SetterAction<any>) {\n const value = resolveValue(next, this._value);\n if (this._value !== value) {\n this._value = value;\n\n // Clear Dirty and Pending so _computedGetter skips updateComputed\n this._flags &= ~(ReactiveFlags.Dirty | ReactiveFlags.Pending);\n\n // Manually push the Dirty flag to all subscribers\n let link = this._subs;\n while (link !== undefined) {\n const sub = link._sub;\n const subFlags = sub._flags;\n\n // Only modify and notify if it isn't already queued for an update\n if ((subFlags & (ReactiveFlags.Dirty | ReactiveFlags.Pending)) === 0) {\n // Force the node to be Dirty so it bypasses checkDirty() upon flush\n sub._flags = subFlags | ReactiveFlags.Dirty;\n notify(sub as EffectNode);\n }\n\n link = link._nextSub;\n }\n\n // Trigger queued effects\n if (!batchDepth) {\n flush();\n }\n }\n return value;\n}\n\nfunction computedAccessor<T>(this: ComputedNode<T>, ...next: [SetterAction<T>]): T {\n if (next.length) {\n return computedSetter.call(this, next[0]) as T;\n } else {\n return computedGetter.call(this) as T;\n }\n}\n\nfunction valueGetter<T>(this: ValueNode<T>): T {\n if (this._flags & ReactiveFlags.Dirty) {\n if (updateValue(this)) {\n const subs = this._subs;\n if (subs !== undefined) {\n shallowPropagate(subs);\n }\n }\n }\n let sub = activeSub;\n while (sub !== undefined) {\n if (sub._flags & (ReactiveFlags.Mutable | ReactiveFlags.Watching)) {\n link(this, sub, cycle);\n break;\n }\n sub = sub._subs?._sub;\n }\n return this._currentValue;\n}\n\nfunction valueSetter<T>(this: ValueNode<T>, next: SetterAction<T>): void {\n const value = resolveValue(next, this._pendingValue);\n if (this._pendingValue !== (this._pendingValue = value)) {\n this._flags = ReactiveFlags.Mutable | ReactiveFlags.Dirty;\n const subs = this._subs;\n if (subs !== undefined) {\n propagate(subs);\n if (!batchDepth) {\n flush();\n }\n }\n }\n}\n\nfunction valueAccessor<T>(this: ValueNode<T>, ...args: [SetterAction<T>]): T | void {\n if (args.length) {\n return valueSetter.call(this, args[0]);\n } else {\n return valueGetter.call(this) as T;\n }\n}\n\nfunction effectCleanup(this: ReactiveNode): void {\n this._depsTail = undefined;\n this._flags = ReactiveFlags.None;\n purgeDeps(this);\n const sub = this._subs;\n if (sub !== undefined) {\n unlink(sub);\n }\n (this as EffectNode)._cleanup?.();\n (this as EffectNode)._cleanup = undefined;\n}\n\n/*==================================*\\\n|| Public API ||\n\\*==================================*/\n\n/**\n * Returns the currently held value. Registers the state as a dependency when called within a tracking context.\n */\nexport type Getter<T> = () => T;\n\n/**\n * A value that may be a static value or a getter function.\n * Can be converted to a plain value with `unwrap`.\n */\nexport type MaybeGetter<T> = T | Getter<T>;\n\n/**\n * Updates the value of an atom. Takes a new plain value, or an update function to compute one.\n */\nexport type Setter<T> = (next: SetterAction<T>) => T;\nexport type SetterAction<T> = T | ((prev: T) => T);\n\n/**\n * A getter and setter pair, as returned from `createAtom`.\n */\nexport type AtomAccessors<T> = [Getter<T>, Setter<T>];\n\n/**\n * Creates a new atom with a default `undefined` value.\n * Returns a `[getter, setter]` function tuple.\n *\n * @example\n * const [getValue, setValue] = createAtom();\n */\nexport function createAtom<T>(): AtomAccessors<T | undefined>;\n\n/**\n * Creates a new atom with a value computed from an existing getter.\n * This is usually used to create a 'settable' getter, in which you can store\n * a temporary value until it gets overwritten by a _real_ update.\n *\n * @example\n * const [getValue, setValue] = createAtom(\"\");\n * const [getInputValue, setInputValue] = createAtom(getValue);\n *\n * setInputValue(\"temporary\");\n * getValue(\"\");\n * getInputValue(); // \"temporary\"\n *\n * setValue(\"overwritten\");\n * getValue(\"overwritten\");\n * getInputValue(); // \"overwritten\"\n */\nexport function createAtom<T>(compute: Getter<T>): AtomAccessors<T>;\n\n/**\n * Creates a new atom with an initial value.\n * Returns a `[getter, setter]` function tuple.\n *\n * @example\n * const [getCount, setCount] = createAtom(5);\n */\nexport function createAtom<T>(initialValue: T): AtomAccessors<T>;\n\nexport function createAtom<T>(value?: T) {\n if (isFunction<Getter<T>>(value)) {\n const node: ComputedNode<T> = {\n _value: undefined,\n _subs: undefined,\n _subsTail: undefined,\n _deps: undefined,\n _depsTail: undefined,\n _flags: ReactiveFlags.None,\n _getter: value as (previousValue?: T | undefined) => T,\n };\n return [computedGetter.bind(node), computedSetter.bind(node)];\n } else {\n const node: ValueNode<T> = {\n _currentValue: value as T,\n _pendingValue: value as T,\n _subs: undefined,\n _subsTail: undefined,\n _flags: ReactiveFlags.Mutable,\n };\n return [valueGetter.bind(node), valueSetter.bind(node)];\n }\n}\n\nexport function compose<T>(getter: (previousValue?: T) => Getter<T> | T): Getter<T> {\n return computedGetter.bind({\n _value: undefined,\n _subs: undefined,\n _subsTail: undefined,\n _deps: undefined,\n _depsTail: undefined,\n _flags: ReactiveFlags.None,\n _getter: getter as (previousValue?: unknown) => unknown,\n }) as () => T;\n}\n\nexport function createEffect(fn: () => void): () => void {\n const e: EffectNode = {\n _fn: fn,\n _cleanup: undefined,\n _subs: undefined,\n _subsTail: undefined,\n _deps: undefined,\n _depsTail: undefined,\n _flags: ReactiveFlags.Watching | ReactiveFlags.RecursedCheck,\n };\n const prevSub = setActiveSub(e);\n if (prevSub !== undefined) {\n link(e, prevSub, 0);\n }\n try {\n const result = e._fn();\n if (isFunction(result)) e._cleanup = result;\n } finally {\n activeSub = prevSub;\n e._flags &= ~ReactiveFlags.RecursedCheck;\n }\n return effectCleanup.bind(e);\n}\n\n/**\n * Unwraps a `MaybeGetter<T>` into a plain `T`.\n * Tracks the value if it is a getter.\n * Use the non-tracking `peek` if you're being stealthy.\n */\nexport function unwrap<T>(value: T | Getter<T>): T {\n if (isFunction<Getter<T>>(value)) {\n return value();\n } else {\n return value;\n }\n}\n\n/**\n * Unwraps a `MaybeGetter<T>` into a plain `T`. Will _not_ track if the value is a getter.\n */\nexport function peek<T>(value: T | Getter<T>): T {\n const prevSub = setActiveSub(undefined);\n try {\n return unwrap(value);\n } finally {\n setActiveSub(prevSub);\n }\n}\n\n/**\n * Groups several signal changes into a single transaction.\n * Suspends effects until `callback` finishes, then runs all updates at once.\n */\nexport function batch(callback: () => void): void {\n ++batchDepth;\n try {\n callback();\n } finally {\n if (!--batchDepth) {\n flush();\n }\n }\n}\n\nexport function subscribe<T>(target: Getter<T>, fn: (value: T) => any): () => void {\n return createEffect(() => {\n const value = target();\n peek(() => fn(value));\n });\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { Context } from "../core/context.js";
|
|
2
|
+
import { DollaPlugin } from "../core/root.js";
|
|
3
|
+
import { type Getter } from "../core/signals.js";
|
|
4
|
+
/**
|
|
5
|
+
* A JSON object of translated strings. Values can be string templates or nested objects.
|
|
6
|
+
*/
|
|
7
|
+
export interface LocalizedStrings extends Record<string, string | LocalizedStrings> {
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* A function that returns an object of localized strings.
|
|
11
|
+
*/
|
|
12
|
+
export type TranslationFetchFn = () => LocalizedStrings | Promise<LocalizedStrings>;
|
|
13
|
+
export type TOptions = {
|
|
14
|
+
/**
|
|
15
|
+
*
|
|
16
|
+
*/
|
|
17
|
+
count?: Getter<number> | number;
|
|
18
|
+
/**
|
|
19
|
+
*
|
|
20
|
+
*/
|
|
21
|
+
context?: Getter<string> | string;
|
|
22
|
+
[value: string]: Getter<any> | any;
|
|
23
|
+
};
|
|
24
|
+
export type LookupFn = (selector: string, options?: TOptions) => string;
|
|
25
|
+
export type Formatter = (locale: string, value: any, options: Record<string, any>) => string;
|
|
26
|
+
type BuiltInFormatters = {
|
|
27
|
+
number: [number | bigint, Intl.NumberFormatOptions?];
|
|
28
|
+
datetime: [Date, Intl.DateTimeFormatOptions?];
|
|
29
|
+
list: [Iterable<string>, Intl.ListFormatOptions?];
|
|
30
|
+
};
|
|
31
|
+
export interface Translator {
|
|
32
|
+
/**
|
|
33
|
+
* An array of locale names for all translations the app supports.
|
|
34
|
+
*/
|
|
35
|
+
supportedLocales: string[];
|
|
36
|
+
/**
|
|
37
|
+
* A Readable containing the currently loaded locale.
|
|
38
|
+
*/
|
|
39
|
+
currentLocale: Getter<string>;
|
|
40
|
+
/**
|
|
41
|
+
* Updates the locale, fetching any translation files as required.
|
|
42
|
+
* Returns a promise that resolves when the new locale is applied.
|
|
43
|
+
*
|
|
44
|
+
* If `name` is undefined the library will try to match the browser language automatically.
|
|
45
|
+
*/
|
|
46
|
+
setLocale(name?: string): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* Returns a Readable of the value at `key`.
|
|
49
|
+
|
|
50
|
+
* @param selector - Key to the translated value.
|
|
51
|
+
* @param options - A map of `{{placeholder}}` names and the values to replace them with.
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* const value = t("your.key.here", { count: 5 });
|
|
55
|
+
*/
|
|
56
|
+
t(selector: string, options?: TOptions): Getter<string>;
|
|
57
|
+
format<K extends keyof BuiltInFormatters, V extends BuiltInFormatters[K][0], O extends BuiltInFormatters[K][1]>(name: K, value: Getter<V> | V, options?: O): Getter<string>;
|
|
58
|
+
format<V, O>(name: string, value: Getter<V> | V, options?: O): Getter<string>;
|
|
59
|
+
}
|
|
60
|
+
export interface TranslatorOptions {
|
|
61
|
+
translations: Record<string, LocalizedStrings | TranslationFetchFn>;
|
|
62
|
+
/**
|
|
63
|
+
* Default locale to load on startup. The translator will try to match the user's browser language if left undefined.
|
|
64
|
+
*/
|
|
65
|
+
locale?: string;
|
|
66
|
+
formatters?: Record<string, Formatter>;
|
|
67
|
+
}
|
|
68
|
+
export declare function createTranslatePlugin(options: TranslatorOptions): DollaPlugin;
|
|
69
|
+
export declare function getTranslate(context: Context): Translator;
|
|
70
|
+
/**
|
|
71
|
+
* Compiles an object of translated strings into a set of function templates.
|
|
72
|
+
*/
|
|
73
|
+
export declare function compile(strings: {
|
|
74
|
+
[key: string]: any;
|
|
75
|
+
}, path?: string[]): [string, CompiledTemplate][];
|
|
76
|
+
export type TemplateSegmentFn = (options: Record<string, any> | undefined, formatters: Map<string, Formatter>, locale: string) => string;
|
|
77
|
+
export type CompiledTemplate = TemplateSegmentFn[];
|
|
78
|
+
/**
|
|
79
|
+
* Parse a string template into an array of functions that will produce each piece of the output when called.
|
|
80
|
+
*/
|
|
81
|
+
export declare function parseTemplate(template: string): CompiledTemplate;
|
|
82
|
+
export {};
|