@fairfox/polly 0.75.2 → 0.76.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/dist/src/actions/index.js +4 -2
- package/dist/src/actions/index.js.map +3 -3
- package/dist/src/client/index.js +2 -2
- package/dist/src/client/index.js.map +2 -2
- package/dist/src/polly-ui/Button.d.ts +4 -0
- package/dist/src/polly-ui/index.css +37 -9
- package/dist/src/polly-ui/index.js +15 -5
- package/dist/src/polly-ui/index.js.map +5 -5
- package/dist/src/polly-ui/markdown.js +3 -3
- package/dist/src/polly-ui/markdown.js.map +2 -2
- package/dist/src/polly-ui/styles.css +37 -9
- package/dist/src/polly-ui/theme.css +19 -0
- package/dist/tools/test/src/visual/index.js +24 -24
- package/dist/tools/test/src/visual/index.js.map +2 -2
- package/package.json +1 -1
|
@@ -156,7 +156,7 @@ function parseActionData(element) {
|
|
|
156
156
|
return data;
|
|
157
157
|
}
|
|
158
158
|
function closeTopOverlay2() {
|
|
159
|
-
const overlays = document.querySelectorAll("[data-overlay-id]");
|
|
159
|
+
const overlays = document.querySelectorAll("[data-overlay-id]:popover-open, dialog[data-overlay-id][open]");
|
|
160
160
|
if (overlays.length === 0)
|
|
161
161
|
return;
|
|
162
162
|
const topOverlay2 = overlays[overlays.length - 1];
|
|
@@ -221,6 +221,8 @@ function installEventDelegation(onDispatch, options = {}) {
|
|
|
221
221
|
const clickedOverlay = event.target.closest("[data-overlay-id]");
|
|
222
222
|
if (clickedOverlay)
|
|
223
223
|
return;
|
|
224
|
+
if (event.target.closest("button[popovertarget]"))
|
|
225
|
+
return;
|
|
224
226
|
if (options.onOutsideOverlayClick) {
|
|
225
227
|
options.onOutsideOverlayClick();
|
|
226
228
|
} else {
|
|
@@ -522,4 +524,4 @@ export {
|
|
|
522
524
|
ACTION_EVENT_TYPES
|
|
523
525
|
};
|
|
524
526
|
|
|
525
|
-
//# debugId=
|
|
527
|
+
//# debugId=ABA512A41C3BA87D64756E2164756E21
|
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"/**\n * Global error surface for action handlers.\n *\n * Actions that fail set the errorState signal via `submitError`; a `<Toast>`\n * component consumes that signal and renders a dismissable message. Handlers\n * that catch expected failures (validation, quota) may call `setError` directly.\n */\n\nimport { signal } from \"@preact/signals\";\n\nexport type ErrorSeverity = \"error\" | \"warning\" | \"info\";\n\nexport type ErrorEntry = {\n id: string;\n message: string;\n severity: ErrorSeverity;\n action?: string;\n createdAt: number;\n};\n\nexport const errorState = signal<ErrorEntry[]>([]);\n\nlet nextId = 0;\nfunction allocId(): string {\n nextId += 1;\n return `polly-err-${nextId}`;\n}\n\nexport function setError(\n message: string,\n opts: { severity?: ErrorSeverity; action?: string } = {}\n): string {\n const entry: ErrorEntry = {\n id: allocId(),\n message,\n severity: opts.severity ?? \"error\",\n action: opts.action,\n createdAt: Date.now(),\n };\n errorState.value = [...errorState.value, entry];\n return entry.id;\n}\n\nexport function clearError(id?: string): void {\n if (id === undefined) {\n errorState.value = [];\n return;\n }\n errorState.value = errorState.value.filter((e) => e.id !== id);\n}\n\n/**\n * Convenience wrapper for an action's catch block.\n * Logs the action name + error and surfaces a user-visible message.\n */\nexport function submitError(action: string, err: unknown): string {\n const message = err instanceof Error ? err.message : String(err);\n return setError(message, { action, severity: \"error\" });\n}\n",
|
|
6
6
|
"/**\n * Overlay registry.\n *\n * Tracks the stack of open overlays (modals, popovers, confirm dialogs) so\n * Escape can close the topmost and `data-overlay-id`-based DOM scans have\n * a mirror in memory. Each entry stores an id plus an optional close\n * callback; `closeTopOverlay` invokes the callback and pops the entry.\n */\n\nimport { signal } from \"@preact/signals\";\n\nexport type OverlayEntry = {\n id: string;\n onClose?: () => void;\n};\n\nconst stack = signal<OverlayEntry[]>([]);\n\n/** Current overlay stack as a read-only snapshot. */\nexport function overlayStack(): readonly OverlayEntry[] {\n return stack.value;\n}\n\n/** Is any overlay currently open? */\nexport function hasOpenOverlay(): boolean {\n return stack.value.length > 0;\n}\n\n/** The top of the stack, or undefined if empty. */\nexport function topOverlay(): OverlayEntry | undefined {\n const s = stack.value;\n return s[s.length - 1];\n}\n\n/** Push an overlay onto the stack. Returns the popped entry when closed. */\nexport function pushOverlay(entry: OverlayEntry): void {\n stack.value = [...stack.value, entry];\n}\n\n/** Pop a specific overlay by id (or the top if no id given). */\nexport function popOverlay(id?: string): OverlayEntry | undefined {\n const s = stack.value;\n if (s.length === 0) return undefined;\n if (id === undefined) {\n const top = s[s.length - 1];\n stack.value = s.slice(0, -1);\n return top;\n }\n const idx = s.findIndex((e) => e.id === id);\n if (idx === -1) return undefined;\n const entry = s[idx];\n stack.value = [...s.slice(0, idx), ...s.slice(idx + 1)];\n return entry;\n}\n\n/** Close the top overlay by calling its onClose and popping it. */\nexport function closeTopOverlay(): OverlayEntry | undefined {\n const top = topOverlay();\n if (!top) return undefined;\n top.onClose?.();\n return popOverlay(top.id);\n}\n\n/** Reset the stack. Intended for tests. */\nexport function resetOverlayStack(): void {\n stack.value = [];\n}\n",
|
|
7
|
-
"/**\n * Event delegation core.\n *\n * One document listener dispatches `data-action` events to typed handlers.\n * Walks up the DOM with `closest('[data-action]')`, parses `data-action-*`\n * attributes into a camelCase object, and hands the dispatch to the caller.\n *\n * Forms are skipped on click — a `<form data-action=\"...\">` responds to\n * submit only, so clicks on form children don't bubble into its action.\n * Escape closes the topmost overlay by calling the overlay registry.\n * Enter/Space on non-interactive elements with `data-action` fire the\n * action (Space is prevented to stop page scroll). Click outside any\n * `[data-overlay-id]` element also pops the top overlay.\n */\n\nimport { closeTopOverlay as closeTopRegistryOverlay } from \"./overlay.ts\";\n\n/** Elements that natively fire click on Enter/Space. */\nexport const INTERACTIVE_TAGS = new Set([\"BUTTON\", \"A\", \"INPUT\", \"SELECT\", \"TEXTAREA\"]);\n\n/** Event types that may trigger a data-action dispatch. */\nexport const ACTION_EVENT_TYPES = new Set([\"click\", \"submit\", \"change\", \"input\"]);\n\n/** Parsed action dispatch — what the runtime resolves before invoking a handler. */\nexport type ActionDispatch = {\n action: string;\n element: HTMLElement;\n event: Event;\n data: Record<string, string>;\n};\n\n/**\n * Parse `data-action-*` attributes into camelCase key-value pairs.\n *\n * `data-action-text-set-id=\"42\"` becomes `{ textSetId: \"42\" }`.\n */\nexport function parseActionData(element: HTMLElement): Record<string, string> {\n const data: Record<string, string> = {};\n for (const attr of Array.from(element.attributes)) {\n if (attr.name.startsWith(\"data-action-\")) {\n const key = attr.name\n .replace(\"data-action-\", \"\")\n .replace(/-([a-z])/g, (_m: string, letter: string) => letter.toUpperCase());\n data[key] = attr.value;\n }\n }\n return data;\n}\n\n/**\n * Close the topmost overlay by dispatching `overlay:close` on its element.\n * Overlays mark themselves with `data-overlay-id`.\n */\nexport function closeTopOverlay(): void {\n const overlays = document.querySelectorAll(\"[data-overlay-id]\");\n if (overlays.length === 0) return;\n const topOverlay = overlays[overlays.length - 1];\n if (!topOverlay) return;\n topOverlay.dispatchEvent(\n new CustomEvent(\"overlay:close\", {\n bubbles: true,\n detail: { id: topOverlay.getAttribute(\"data-overlay-id\") },\n })\n );\n}\n\n/**\n * Resolve a DOM event to an ActionDispatch, or null if no data-action matches.\n */\nexport function resolveAction(event: Event): ActionDispatch | null {\n const target = event.target;\n if (!(target instanceof Element)) return null;\n const actionElement = target.closest(\"[data-action]\");\n if (!(actionElement instanceof HTMLElement)) return null;\n if (event.type === \"click\" && actionElement.tagName === \"FORM\") return null;\n const action = actionElement.getAttribute(\"data-action\");\n if (!action) return null;\n return {\n action,\n element: actionElement,\n event,\n data: parseActionData(actionElement),\n };\n}\n\n/**\n * Install document-level listeners for the delegation system.\n * Returns a cleanup function that removes every listener it installed.\n */\nexport function installEventDelegation(\n onDispatch: (dispatch: ActionDispatch) => void,\n options: { onEscape?: () => void; onOutsideOverlayClick?: () => void } = {}\n): () => void {\n const handleActionEvent = (event: Event) => {\n const dispatch = resolveAction(event);\n if (dispatch) onDispatch(dispatch);\n };\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n if (options.onEscape) {\n options.onEscape();\n } else {\n closeTopRegistryOverlay();\n closeTopOverlay();\n }\n return;\n }\n if (event.key === \"Enter\" || event.key === \" \") {\n const target = event.target;\n if (!(target instanceof Element)) return;\n if (INTERACTIVE_TAGS.has(target.tagName)) return;\n const dispatch = resolveAction(event);\n if (dispatch) {\n event.preventDefault();\n onDispatch(dispatch);\n }\n }\n };\n\n const handleMouseDown = (event: MouseEvent) => {\n if (!(event.target instanceof Element)) return;\n const clickedOverlay = event.target.closest(\"[data-overlay-id]\");\n if (clickedOverlay) return;\n if (options.onOutsideOverlayClick) {\n options.onOutsideOverlayClick();\n } else {\n closeTopRegistryOverlay();\n closeTopOverlay();\n }\n };\n\n for (const eventType of ACTION_EVENT_TYPES) {\n document.addEventListener(eventType, handleActionEvent);\n }\n document.addEventListener(\"keydown\", handleKeyDown);\n document.addEventListener(\"mousedown\", handleMouseDown);\n\n return () => {\n for (const eventType of ACTION_EVENT_TYPES) {\n document.removeEventListener(eventType, handleActionEvent);\n }\n document.removeEventListener(\"keydown\", handleKeyDown);\n document.removeEventListener(\"mousedown\", handleMouseDown);\n };\n}\n",
|
|
7
|
+
"/**\n * Event delegation core.\n *\n * One document listener dispatches `data-action` events to typed handlers.\n * Walks up the DOM with `closest('[data-action]')`, parses `data-action-*`\n * attributes into a camelCase object, and hands the dispatch to the caller.\n *\n * Forms are skipped on click — a `<form data-action=\"...\">` responds to\n * submit only, so clicks on form children don't bubble into its action.\n * Escape closes the topmost overlay by calling the overlay registry.\n * Enter/Space on non-interactive elements with `data-action` fire the\n * action (Space is prevented to stop page scroll). Click outside any\n * `[data-overlay-id]` element also pops the top overlay.\n */\n\nimport { closeTopOverlay as closeTopRegistryOverlay } from \"./overlay.ts\";\n\n/** Elements that natively fire click on Enter/Space. */\nexport const INTERACTIVE_TAGS = new Set([\"BUTTON\", \"A\", \"INPUT\", \"SELECT\", \"TEXTAREA\"]);\n\n/** Event types that may trigger a data-action dispatch. */\nexport const ACTION_EVENT_TYPES = new Set([\"click\", \"submit\", \"change\", \"input\"]);\n\n/** Parsed action dispatch — what the runtime resolves before invoking a handler. */\nexport type ActionDispatch = {\n action: string;\n element: HTMLElement;\n event: Event;\n data: Record<string, string>;\n};\n\n/**\n * Parse `data-action-*` attributes into camelCase key-value pairs.\n *\n * `data-action-text-set-id=\"42\"` becomes `{ textSetId: \"42\" }`.\n */\nexport function parseActionData(element: HTMLElement): Record<string, string> {\n const data: Record<string, string> = {};\n for (const attr of Array.from(element.attributes)) {\n if (attr.name.startsWith(\"data-action-\")) {\n const key = attr.name\n .replace(\"data-action-\", \"\")\n .replace(/-([a-z])/g, (_m: string, letter: string) => letter.toUpperCase());\n data[key] = attr.value;\n }\n }\n return data;\n}\n\n/**\n * Close the topmost overlay by dispatching `overlay:close` on its element.\n * Overlays mark themselves with `data-overlay-id`.\n */\nexport function closeTopOverlay(): void {\n const overlays = document.querySelectorAll(\n \"[data-overlay-id]:popover-open, dialog[data-overlay-id][open]\"\n );\n if (overlays.length === 0) return;\n const topOverlay = overlays[overlays.length - 1];\n if (!topOverlay) return;\n topOverlay.dispatchEvent(\n new CustomEvent(\"overlay:close\", {\n bubbles: true,\n detail: { id: topOverlay.getAttribute(\"data-overlay-id\") },\n })\n );\n}\n\n/**\n * Resolve a DOM event to an ActionDispatch, or null if no data-action matches.\n */\nexport function resolveAction(event: Event): ActionDispatch | null {\n const target = event.target;\n if (!(target instanceof Element)) return null;\n const actionElement = target.closest(\"[data-action]\");\n if (!(actionElement instanceof HTMLElement)) return null;\n if (event.type === \"click\" && actionElement.tagName === \"FORM\") return null;\n const action = actionElement.getAttribute(\"data-action\");\n if (!action) return null;\n return {\n action,\n element: actionElement,\n event,\n data: parseActionData(actionElement),\n };\n}\n\n/**\n * Install document-level listeners for the delegation system.\n * Returns a cleanup function that removes every listener it installed.\n */\nexport function installEventDelegation(\n onDispatch: (dispatch: ActionDispatch) => void,\n options: { onEscape?: () => void; onOutsideOverlayClick?: () => void } = {}\n): () => void {\n const handleActionEvent = (event: Event) => {\n const dispatch = resolveAction(event);\n if (dispatch) onDispatch(dispatch);\n };\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n if (options.onEscape) {\n options.onEscape();\n } else {\n closeTopRegistryOverlay();\n closeTopOverlay();\n }\n return;\n }\n if (event.key === \"Enter\" || event.key === \" \") {\n const target = event.target;\n if (!(target instanceof Element)) return;\n if (INTERACTIVE_TAGS.has(target.tagName)) return;\n const dispatch = resolveAction(event);\n if (dispatch) {\n event.preventDefault();\n onDispatch(dispatch);\n }\n }\n };\n\n const handleMouseDown = (event: MouseEvent) => {\n if (!(event.target instanceof Element)) return;\n const clickedOverlay = event.target.closest(\"[data-overlay-id]\");\n if (clickedOverlay) return;\n if (event.target.closest(\"button[popovertarget]\")) return;\n if (options.onOutsideOverlayClick) {\n options.onOutsideOverlayClick();\n } else {\n closeTopRegistryOverlay();\n closeTopOverlay();\n }\n };\n\n for (const eventType of ACTION_EVENT_TYPES) {\n document.addEventListener(eventType, handleActionEvent);\n }\n document.addEventListener(\"keydown\", handleKeyDown);\n document.addEventListener(\"mousedown\", handleMouseDown);\n\n return () => {\n for (const eventType of ACTION_EVENT_TYPES) {\n document.removeEventListener(eventType, handleActionEvent);\n }\n document.removeEventListener(\"keydown\", handleKeyDown);\n document.removeEventListener(\"mousedown\", handleMouseDown);\n };\n}\n",
|
|
8
8
|
"/**\n * Form primitive.\n *\n * `createForm` returns a typed form store: per-field signals, an aggregated\n * values signal, open/close/submit methods, and three auto-registered action\n * handlers (`{name}:open`, `{name}:close`, `{name}:submit`) that callers spread\n * into their global action registry.\n *\n * Lifecycle:\n * open → resets fields to initialValues, applies onOpen overrides,\n * sets isOpen = true, records data-action-* data in openParams\n * typing → uncontrolled inputs keep their own state; controlled inputs\n * write fields.X.value directly\n * submit → reads FormData from the form element, merges into fields,\n * runs optional validate, calls user onSubmit with final values,\n * closes on success, sets errorState on failure\n * close → resets and sets isOpen = false\n * guard → autonomous effect; if guard() returns false while open, close()\n */\n\nimport { computed, effect, type ReadonlySignal, type Signal, signal } from \"@preact/signals\";\nimport { submitError } from \"./error.ts\";\nimport type { ActionRegistry } from \"./registry.ts\";\n\nfunction isFormElement(target: EventTarget | null): target is HTMLFormElement {\n if (!target) return false;\n if (typeof HTMLFormElement !== \"undefined\") {\n return target instanceof HTMLFormElement;\n }\n const t = target as unknown as { tagName?: unknown };\n return typeof t.tagName === \"string\" && t.tagName === \"FORM\";\n}\n\nexport type FormOpenContext<TStores> = {\n data: Record<string, string>;\n stores: TStores;\n};\n\nexport type FormSubmitContext<TValues, TStores> = {\n values: TValues;\n stores: TStores;\n};\n\nexport type FormConfig<TValues extends Record<string, string>, TStores> = {\n /** Used as action namespace: `{name}:open`, `{name}:close`, `{name}:submit`. */\n name: string;\n initialValues: TValues;\n onSubmit: (ctx: FormSubmitContext<TValues, TStores>) => void | Promise<void>;\n /** Invoked on open; return partial overrides to pre-populate fields. */\n onOpen?: (ctx: FormOpenContext<TStores>) => Partial<TValues> | undefined;\n /** Returns false while open → form auto-closes (entity-deletion guard). */\n guard?: (ctx: { stores: TStores }) => boolean;\n /** Synchronous validation. Returning keys blocks submit. */\n validate?: (values: TValues) => Partial<Record<keyof TValues, string>> | null;\n};\n\nexport type FormStore<TValues extends Record<string, string>, TStores> = {\n readonly name: string;\n readonly isOpen: ReadonlySignal<boolean>;\n readonly values: ReadonlySignal<TValues>;\n readonly fields: { [K in keyof TValues]: Signal<TValues[K]> };\n readonly errors: ReadonlySignal<Partial<Record<keyof TValues, string>>>;\n readonly isSubmitting: ReadonlySignal<boolean>;\n readonly openParams: ReadonlySignal<Record<string, string>>;\n open(override?: Partial<TValues>, params?: Record<string, string>): void;\n close(): void;\n submit(event?: Event): Promise<void>;\n /** Late-binds stores; required before guard/onOpen/onSubmit can access stores. */\n bindStores(getStores: () => TStores): void;\n /** Action handler entries. Spread into the user's ActionRegistry. */\n actions: ActionRegistry<TStores>;\n};\n\nexport function createForm<TValues extends Record<string, string>, TStores>(\n config: FormConfig<TValues, TStores>\n): FormStore<TValues, TStores> {\n const fieldKeys = Object.keys(config.initialValues) as unknown as (keyof TValues)[];\n\n const fields = {} as unknown as { [K in keyof TValues]: Signal<TValues[K]> };\n for (const key of fieldKeys) {\n fields[key] = signal(config.initialValues[key]);\n }\n\n const values = computed<TValues>(() => {\n const v = {} as unknown as TValues;\n for (const key of fieldKeys) {\n v[key] = fields[key].value;\n }\n return v;\n });\n\n const isOpen = signal(false);\n const isSubmitting = signal(false);\n const errors = signal<Partial<Record<keyof TValues, string>>>({});\n const openParams = signal<Record<string, string>>({});\n\n let getStoresRef: (() => TStores) | null = null;\n let disposeGuardEffect: (() => void) | null = null;\n\n function getStoresOrThrow(): TStores {\n if (!getStoresRef) {\n throw new Error(\n `Form \"${config.name}\" used before bindStores(). Call form.bindStores(() => yourStores) at app init.`\n );\n }\n return getStoresRef();\n }\n\n function resetToInitial(): void {\n for (const key of fieldKeys) {\n fields[key].value = config.initialValues[key];\n }\n errors.value = {};\n }\n\n // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: open applies two layers of overrides plus optional onOpen — branchy by design.\n function open(override?: Partial<TValues>, params: Record<string, string> = {}): void {\n resetToInitial();\n openParams.value = params;\n if (config.onOpen && getStoresRef) {\n const onOpenOverride = config.onOpen({ data: params, stores: getStoresOrThrow() }) ?? {};\n for (const [k, v] of Object.entries(onOpenOverride)) {\n if (k in fields) {\n fields[k as keyof TValues].value = v as TValues[keyof TValues];\n }\n }\n }\n if (override) {\n for (const [k, v] of Object.entries(override)) {\n if (k in fields) {\n fields[k as keyof TValues].value = v as TValues[keyof TValues];\n }\n }\n }\n isOpen.value = true;\n }\n\n function close(): void {\n isOpen.value = false;\n resetToInitial();\n openParams.value = {};\n }\n\n // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: submit funnels FormData, validate, onSubmit, errorState, and close — one-path-per-stage by design.\n async function submit(event?: Event): Promise<void> {\n if (event) event.preventDefault();\n if (event && isFormElement(event.target)) {\n const fd = new FormData(event.target);\n for (const key of fieldKeys) {\n const raw = fd.get(key as unknown as string);\n if (raw !== null) {\n fields[key].value = String(raw) as unknown as TValues[typeof key];\n }\n }\n }\n const current = values.value;\n const validationErrors = config.validate?.(current);\n if (validationErrors && Object.keys(validationErrors).length > 0) {\n errors.value = validationErrors;\n return;\n }\n errors.value = {};\n isSubmitting.value = true;\n try {\n await config.onSubmit({\n values: current,\n stores: getStoresOrThrow(),\n });\n close();\n } catch (err) {\n submitError(`${config.name}:submit`, err);\n } finally {\n isSubmitting.value = false;\n }\n }\n\n function bindStores(getStores: () => TStores): void {\n getStoresRef = getStores;\n disposeGuardEffect?.();\n const guardFn = config.guard;\n if (guardFn) {\n disposeGuardEffect = effect(() => {\n if (!isOpen.value) return;\n if (!guardFn({ stores: getStores() })) close();\n });\n }\n }\n\n const actions: ActionRegistry<TStores> = {\n [`${config.name}:open`]: ({ data }) => {\n open(undefined, data);\n },\n [`${config.name}:close`]: () => {\n close();\n },\n [`${config.name}:submit`]: async ({ event }) => {\n await submit(event);\n },\n };\n\n return {\n name: config.name,\n isOpen,\n values,\n fields,\n errors,\n isSubmitting,\n openParams,\n open,\n close,\n submit,\n bindStores,\n actions,\n };\n}\n\n/**\n * Compose many forms into a single set: merged actions, closeAll, openForm signal.\n */\nexport type FormSet<TStores> = {\n actions: ActionRegistry<TStores>;\n openForm: ReadonlySignal<string | null>;\n closeAll(): void;\n bindStores(getStores: () => TStores): void;\n};\n\nexport function createFormSet<TStores>(\n forms: readonly FormStore<Record<string, string>, TStores>[]\n): FormSet<TStores> {\n const merged: ActionRegistry<TStores> = {};\n for (const form of forms) {\n Object.assign(merged, form.actions);\n }\n\n const openForm = computed<string | null>(() => {\n for (const form of forms) {\n if (form.isOpen.value) return form.name;\n }\n return null;\n });\n\n return {\n actions: merged,\n openForm,\n closeAll() {\n for (const form of forms) form.close();\n },\n bindStores(getStores) {\n for (const form of forms) form.bindStores(getStores);\n },\n };\n}\n",
|
|
9
9
|
"/**\n * Store base + Preact context.\n *\n * `createStore` is a thin convention-enforcer: a typed bag of signals\n * plus methods. Apps use it to define domain stores whose only public\n * mutation surface is named methods (actions call them; components read\n * signals and dispatch actions). No cleverness — a named pattern more\n * than a library.\n *\n * `StoreProvider` + `useStores` wire the stores bag into Preact context\n * so components and the delegation runtime can reach it via a single hook.\n */\n\nimport type { ComponentChildren } from \"preact\";\nimport { createContext } from \"preact\";\nimport { useContext } from \"preact/hooks\";\n\n/**\n * Identity helper; exists so domain stores have a canonical creation\n * call even though the bag itself is a plain object. Centralising here\n * lets us hang additional behaviour off the call site later (debug\n * instrumentation, devtools) without a migration.\n */\nexport function createStore<T extends object>(init: T): T {\n return init;\n}\n\nconst StoreContext = createContext<unknown>(null);\n\nexport type StoreProviderProps<TStores> = {\n children: ComponentChildren;\n stores: TStores;\n};\n\nexport function StoreProvider<TStores>({ children, stores }: StoreProviderProps<TStores>) {\n return <StoreContext.Provider value={stores}>{children}</StoreContext.Provider>;\n}\n\nexport function useStores<TStores>(): TStores {\n const ctx = useContext(StoreContext) as unknown as TStores | null;\n if (ctx === null) {\n throw new Error(\"useStores must be used within a StoreProvider\");\n }\n return ctx;\n}\n",
|
|
10
10
|
"/**\n * Testing helpers for action handlers.\n *\n * Handlers are plain functions taking an ActionContext; these helpers\n * build the context pieces without jsdom. For full-DOM tests use the\n * browser harness at `@fairfox/polly/test/browser`.\n */\n\nimport type { ActionContext, ActionHandler, ActionRegistry } from \"./registry.ts\";\n\n/**\n * Build a mock element that satisfies ActionContext.element.\n * Only the surface a handler is likely to touch is populated.\n */\nexport function createMockElement(\n attrs: Record<string, string> = {},\n tagName = \"DIV\"\n): HTMLElement {\n const attrMap = new Map(Object.entries(attrs));\n const el = {\n tagName,\n nodeType: 1,\n getAttribute: (name: string) => attrMap.get(name) ?? null,\n setAttribute: (name: string, value: string) => {\n attrMap.set(name, value);\n },\n hasAttribute: (name: string) => attrMap.has(name),\n removeAttribute: (name: string) => {\n attrMap.delete(name);\n },\n attributes: Array.from(attrMap.entries()).map(([name, value]) => ({\n name,\n value,\n })),\n } as unknown as HTMLElement;\n return el;\n}\n\n/** Build a minimal submit-like event wrapping a `<form>` FormData payload. */\nexport function createMockSubmitEvent(form: HTMLFormElement | Record<string, string>): Event {\n let target: HTMLFormElement;\n if (typeof HTMLFormElement !== \"undefined\" && form instanceof HTMLFormElement) {\n target = form;\n } else {\n target = createMockFormElement(form as unknown as Record<string, string>);\n }\n let defaultPrevented = false;\n return {\n type: \"submit\",\n target,\n currentTarget: target,\n preventDefault() {\n defaultPrevented = true;\n },\n stopPropagation() {\n /* noop */\n },\n get defaultPrevented() {\n return defaultPrevented;\n },\n } as unknown as Event;\n}\n\nfunction createMockFormElement(fields: Record<string, string>): HTMLFormElement {\n return {\n nodeType: 1,\n tagName: \"FORM\",\n elements: Object.entries(fields).map(([name, value]) => ({\n name,\n value,\n })),\n } as unknown as HTMLFormElement;\n}\n\n/**\n * Shallow-merged partial stores. Callers typically pass signal-backed fakes.\n */\nexport function createMockStores<TStores extends object>(partial: Partial<TStores> = {}): TStores {\n return partial as unknown as TStores;\n}\n\n/**\n * Run a handler in isolation. Useful for unit-testing action logic without\n * wiring the full document event delegation.\n */\nexport async function runAction<TStores>(\n registry: ActionRegistry<TStores>,\n action: string,\n ctx: Partial<ActionContext<TStores>> & { stores: TStores }\n): Promise<void> {\n const handler: ActionHandler<TStores> | undefined = registry[action];\n if (!handler) {\n throw new Error(`No handler registered for action \"${action}\"`);\n }\n const fullCtx: ActionContext<TStores> = {\n stores: ctx.stores,\n event: ctx.event ?? new Event(\"click\"),\n element: ctx.element ?? createMockElement(),\n data: ctx.data ?? {},\n };\n await handler(fullCtx);\n}\n"
|
|
11
11
|
],
|
|
12
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQA;AAYO,IAAM,aAAa,OAAqB,CAAC,CAAC;AAEjD,IAAI,SAAS;AACb,SAAS,OAAO,GAAW;AAAA,EACzB,UAAU;AAAA,EACV,OAAO,aAAa;AAAA;AAGf,SAAS,QAAQ,CACtB,SACA,OAAsD,CAAC,GAC/C;AAAA,EACR,MAAM,QAAoB;AAAA,IACxB,IAAI,QAAQ;AAAA,IACZ;AAAA,IACA,UAAU,KAAK,YAAY;AAAA,IAC3B,QAAQ,KAAK;AAAA,IACb,WAAW,KAAK,IAAI;AAAA,EACtB;AAAA,EACA,WAAW,QAAQ,CAAC,GAAG,WAAW,OAAO,KAAK;AAAA,EAC9C,OAAO,MAAM;AAAA;AAGR,SAAS,UAAU,CAAC,IAAmB;AAAA,EAC5C,IAAI,OAAO,WAAW;AAAA,IACpB,WAAW,QAAQ,CAAC;AAAA,IACpB;AAAA,EACF;AAAA,EACA,WAAW,QAAQ,WAAW,MAAM,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE;AAAA;AAOxD,SAAS,WAAW,CAAC,QAAgB,KAAsB;AAAA,EAChE,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,EAC/D,OAAO,SAAS,SAAS,EAAE,QAAQ,UAAU,QAAQ,CAAC;AAAA;;AChDxD,mBAAS;AAOT,IAAM,QAAQ,QAAuB,CAAC,CAAC;AAGhC,SAAS,YAAY,GAA4B;AAAA,EACtD,OAAO,MAAM;AAAA;AAIR,SAAS,cAAc,GAAY;AAAA,EACxC,OAAO,MAAM,MAAM,SAAS;AAAA;AAIvB,SAAS,UAAU,GAA6B;AAAA,EACrD,MAAM,IAAI,MAAM;AAAA,EAChB,OAAO,EAAE,EAAE,SAAS;AAAA;AAIf,SAAS,WAAW,CAAC,OAA2B;AAAA,EACrD,MAAM,QAAQ,CAAC,GAAG,MAAM,OAAO,KAAK;AAAA;AAI/B,SAAS,UAAU,CAAC,IAAuC;AAAA,EAChE,MAAM,IAAI,MAAM;AAAA,EAChB,IAAI,EAAE,WAAW;AAAA,IAAG;AAAA,EACpB,IAAI,OAAO,WAAW;AAAA,IACpB,MAAM,MAAM,EAAE,EAAE,SAAS;AAAA,IACzB,MAAM,QAAQ,EAAE,MAAM,GAAG,EAAE;AAAA,IAC3B,OAAO;AAAA,EACT;AAAA,EACA,MAAM,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE;AAAA,EAC1C,IAAI,QAAQ;AAAA,IAAI;AAAA,EAChB,MAAM,QAAQ,EAAE;AAAA,EAChB,MAAM,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,MAAM,MAAM,CAAC,CAAC;AAAA,EACtD,OAAO;AAAA;AAIF,SAAS,eAAe,GAA6B;AAAA,EAC1D,MAAM,MAAM,WAAW;AAAA,EACvB,IAAI,CAAC;AAAA,IAAK;AAAA,EACV,IAAI,UAAU;AAAA,EACd,OAAO,WAAW,IAAI,EAAE;AAAA;AAInB,SAAS,iBAAiB,GAAS;AAAA,EACxC,MAAM,QAAQ,CAAC;AAAA;;;AC/CV,IAAM,mBAAmB,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS,UAAU,UAAU,CAAC;AAG/E,IAAM,qBAAqB,IAAI,IAAI,CAAC,SAAS,UAAU,UAAU,OAAO,CAAC;AAezE,SAAS,eAAe,CAAC,SAA8C;AAAA,EAC5E,MAAM,OAA+B,CAAC;AAAA,EACtC,WAAW,QAAQ,MAAM,KAAK,QAAQ,UAAU,GAAG;AAAA,IACjD,IAAI,KAAK,KAAK,WAAW,cAAc,GAAG;AAAA,MACxC,MAAM,MAAM,KAAK,KACd,QAAQ,gBAAgB,EAAE,EAC1B,QAAQ,aAAa,CAAC,IAAY,WAAmB,OAAO,YAAY,CAAC;AAAA,MAC5E,KAAK,OAAO,KAAK;AAAA,IACnB;AAAA,EACF;AAAA,EACA,OAAO;AAAA;AAOF,SAAS,gBAAe,GAAS;AAAA,EACtC,MAAM,WAAW,SAAS,
|
|
13
|
-
"debugId": "
|
|
12
|
+
"mappings": "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",
|
|
13
|
+
"debugId": "ABA512A41C3BA87D64756E2164756E21",
|
|
14
14
|
"names": []
|
|
15
15
|
}
|
package/dist/src/client/index.js
CHANGED
|
@@ -72,7 +72,7 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
72
72
|
// src/client/wrapper.ts
|
|
73
73
|
import { treaty } from "@elysiajs/eden";
|
|
74
74
|
|
|
75
|
-
// node_modules/.bun/@preact+signals-core@1.14.2/node_modules/@preact/signals-core/dist/signals-core.module.js
|
|
75
|
+
// ../../node_modules/.bun/@preact+signals-core@1.14.2/node_modules/@preact/signals-core/dist/signals-core.module.js
|
|
76
76
|
var i = Symbol.for("preact-signals");
|
|
77
77
|
function t() {
|
|
78
78
|
if (!(s > 1)) {
|
|
@@ -643,4 +643,4 @@ export {
|
|
|
643
643
|
createPollyClient
|
|
644
644
|
};
|
|
645
645
|
|
|
646
|
-
//# debugId=
|
|
646
|
+
//# debugId=74C4CA57821ED6F364756E2164756E21
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/client/wrapper.ts", "
|
|
3
|
+
"sources": ["../src/client/wrapper.ts", "../../../node_modules/.bun/@preact+signals-core@1.14.2/node_modules/@preact/signals-core/dist/signals-core.module.js", "../src/core/clock.ts", "../src/elysia/route-match.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"// @ts-nocheck - Optional peer dependencies (elysia, @elysiajs/eden)\nimport { treaty } from \"@elysiajs/eden\";\nimport { type Signal, signal } from \"@preact/signals-core\";\nimport { createLamportClock } from \"../core/clock\";\nimport { findMatchingConfig } from \"../elysia/route-match\";\nimport type { ClientEffectConfig, PollyResponseMetadata, RoutePattern } from \"../elysia/types\";\n\n/**\n * Offline queue entry\n */\ninterface QueuedRequest {\n id: string;\n method: string;\n path: string;\n body: unknown;\n optimisticResult?: unknown;\n timestamp: number;\n}\n\n/**\n * Client-side state management\n */\ninterface ClientState {\n isOnline: Signal<boolean>;\n isSyncing: Signal<boolean>;\n queuedRequests: Signal<QueuedRequest[]>;\n}\n\n/**\n * Polly client options\n */\nexport interface PollyClientOptions {\n /**\n * Client state signals that should be synced\n */\n state?: Record<string, Signal<unknown>>;\n\n /**\n * Client-side effect handlers, keyed by the same route pattern used in the\n * server config (e.g. `'POST /todos'`). The wrapper looks up handlers here\n * after a successful request — handlers are imported, never shipped from\n * the server.\n */\n clientEffects?: Record<RoutePattern, ClientEffectConfig[\"client\"]>;\n\n /**\n * Callback when online/offline status changes\n */\n onOfflineChange?: (isOnline: boolean) => void;\n\n /**\n * Enable WebSocket for real-time updates (default: true in dev, false in prod)\n */\n websocket?: boolean;\n\n /**\n * WebSocket path (default: '/polly/ws')\n */\n websocketPath?: string;\n}\n\n/**\n * Create a Polly-enhanced Eden client\n *\n * In DEV mode:\n * - Processes server metadata for hot reloading\n * - Executes client effects from server\n * - Handles offline queueing\n * - Connects WebSocket for real-time updates\n *\n * In PROD mode:\n * - Minimal wrapper (client effects are bundled)\n * - Optional WebSocket for real-time features\n * - Offline queueing still works\n *\n * Example:\n * ```typescript\n * import { createPollyClient } from '@fairfox/polly/client';\n * import { $syncedState } from '@fairfox/polly';\n * import type { app } from './server';\n *\n * const clientState = {\n * todos: $syncedState('todos', []),\n * user: $syncedState('user', null),\n * };\n *\n * export const api = createPollyClient<typeof app>('http://localhost:3000', {\n * state: clientState,\n * websocket: true,\n * });\n * ```\n */\nexport function createPollyClient<T extends Record<string, unknown>>(\n url: string,\n options: PollyClientOptions = {}\n) {\n const isDev = process.env.NODE_ENV !== \"production\";\n const baseClient = treaty<T>(url);\n const clock = createLamportClock(\"client\");\n\n // Client state\n const clientState: ClientState = {\n isOnline: signal(typeof navigator === \"undefined\" ? true : navigator.onLine),\n isSyncing: signal(false),\n queuedRequests: signal<QueuedRequest[]>([]),\n };\n\n // WebSocket connection for real-time updates (opt-in in prod)\n let ws: WebSocket | null = null;\n const shouldUseWebSocket = options.websocket === undefined ? isDev : options.websocket;\n\n if (shouldUseWebSocket && typeof WebSocket !== \"undefined\") {\n const wsPath = options.websocketPath || \"/polly/ws\";\n const wsUrl = url.replace(/^http/, \"ws\") + wsPath;\n\n try {\n ws = new WebSocket(wsUrl);\n\n ws.addEventListener(\"open\", () => {\n console.log(\"[Polly] WebSocket connected\");\n });\n\n ws.addEventListener(\"message\", (event) => {\n const message = JSON.parse(event.data);\n\n if (message.type === \"state-sync\") {\n // Initial state sync\n // nosemgrep: javascript.lang.security.insecure-object-assign.insecure-object-assign — `message.state` is already typed wire data delivered by the polly server; the trust boundary is the WebSocket auth, not Object.assign.\n Object.assign(options.state || {}, message.state);\n } else if (message.type === \"effect\") {\n // Remote effect triggered by another client (broadcast)\n console.log(\"[Polly] Received broadcast effect:\", message);\n // In production, handle this via your bundled effects\n // In dev, the effect handler comes from metadata\n }\n });\n\n ws.addEventListener(\"error\", (error) => {\n // biome-ignore lint/suspicious/noConsole: Error logging is intentional\n console.error(\"[Polly] WebSocket error:\", error);\n });\n } catch (error) {\n // biome-ignore lint/suspicious/noConsole: Error logging is intentional\n console.error(\"[Polly] Failed to create WebSocket:\", error);\n }\n }\n\n // Online/offline listeners (browser only)\n if (typeof window !== \"undefined\") {\n window.addEventListener(\"online\", () => {\n clientState.isOnline.value = true;\n options.onOfflineChange?.(true);\n processQueue();\n });\n\n window.addEventListener(\"offline\", () => {\n clientState.isOnline.value = false;\n options.onOfflineChange?.(false);\n });\n }\n\n /**\n * Process queued requests when back online\n */\n // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: Queue processing requires complex branching logic\n async function processQueue() {\n if (clientState.queuedRequests.value.length === 0) return;\n\n clientState.isSyncing.value = true;\n\n const queue = [...clientState.queuedRequests.value];\n clientState.queuedRequests.value = [];\n\n for (const req of queue) {\n try {\n // Replay request\n const response = await fetch(url + req.path, {\n method: req.method,\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(req.body),\n });\n\n const result = await response.json();\n\n // In dev mode, process metadata\n if (isDev) {\n const metadataHeader = response.headers.get(\"X-Polly-Metadata\");\n if (metadataHeader) {\n const metadata: PollyResponseMetadata = JSON.parse(metadataHeader);\n\n // Handle merge if optimistic update was used\n if (req.optimisticResult && metadata.offline?.merge) {\n const mergeStrategy = metadata.offline.merge;\n\n if (mergeStrategy === \"replace\") {\n // Replace optimistic with server result (default)\n // The client effect will handle this\n } else if (typeof mergeStrategy === \"function\") {\n // TODO: call mergeStrategy(req.optimisticResult, result) and apply\n // the merged state to local signals.\n }\n }\n\n // Execute client effect — looked up locally by route, never deserialised from the wire\n if (metadata.hasClientEffect) {\n const handler = findMatchingConfig(options.clientEffects, req.method, req.path);\n if (handler) {\n handler({\n result,\n body: req.body,\n state: { client: options.state || {}, server: {} },\n params: {},\n clock: metadata.clock,\n });\n }\n }\n }\n }\n } catch (error) {\n // biome-ignore lint/suspicious/noConsole: Error logging is intentional\n console.error(\"[Polly] Failed to replay request:\", req, error);\n // Re-queue on failure\n clientState.queuedRequests.value.push(req);\n }\n }\n\n clientState.isSyncing.value = false;\n }\n\n // Return the base client with additional Polly features\n return {\n ...baseClient,\n $polly: {\n state: clientState,\n clock,\n ws,\n /**\n * Manually process queued requests\n */\n sync: processQueue,\n },\n };\n}\n",
|
|
6
6
|
"var i=Symbol.for(\"preact-signals\");function t(){if(!(s>1)){var i,t=!1;!function(){var i=c;c=void 0;while(void 0!==i){if(i.S.v===i.v)i.S.i=i.i;i=i.o}}();while(void 0!==h){var n=h;h=void 0;v++;while(void 0!==n){var r=n.u;n.u=void 0;n.f&=-3;if(!(8&n.f)&&w(n))try{n.c()}catch(n){if(!t){i=n;t=!0}}n=r}}v=0;s--;if(t)throw i}else s--}function n(i){if(s>0)return i();e=++u;s++;try{return i()}finally{t()}}var r=void 0;function o(i){var t=r;r=void 0;try{return i()}finally{r=t}}var f,h=void 0,s=0,v=0,u=0,e=0,c=void 0,d=0;function a(i){if(void 0!==r){var t=i.n;if(void 0===t||t.t!==r){t={i:0,S:i,p:r.s,n:void 0,t:r,e:void 0,x:void 0,r:t};if(void 0!==r.s)r.s.n=t;r.s=t;i.n=t;if(32&r.f)i.S(t);return t}else if(-1===t.i){t.i=0;if(void 0!==t.n){t.n.p=t.p;if(void 0!==t.p)t.p.n=t.n;t.p=r.s;t.n=void 0;r.s.n=t;r.s=t}return t}}}function l(i,t){this.v=i;this.i=0;this.n=void 0;this.t=void 0;this.l=0;this.W=null==t?void 0:t.watched;this.Z=null==t?void 0:t.unwatched;this.name=null==t?void 0:t.name}l.prototype.brand=i;l.prototype.h=function(){return!0};l.prototype.S=function(i){var t=this,n=this.t;if(n!==i&&void 0===i.e){i.x=n;this.t=i;if(void 0!==n)n.e=i;else o(function(){var i;null==(i=t.W)||i.call(t)})}};l.prototype.U=function(i){var t=this;if(void 0!==this.t){var n=i.e,r=i.x;if(void 0!==n){n.x=r;i.e=void 0}if(void 0!==r){r.e=n;i.x=void 0}if(i===this.t){this.t=r;if(void 0===r)o(function(){var i;null==(i=t.Z)||i.call(t)})}}};l.prototype.subscribe=function(i){var t=this;return j(function(){var n=t.value,o=r;r=void 0;try{i(n)}finally{r=o}},{name:\"sub\"})};l.prototype.valueOf=function(){return this.value};l.prototype.toString=function(){return this.value+\"\"};l.prototype.toJSON=function(){return this.value};l.prototype.peek=function(){var i=this;return o(function(){return i.value})};Object.defineProperty(l.prototype,\"value\",{get:function(){var i=a(this);if(void 0!==i)i.i=this.i;return this.v},set:function(i){if(i!==this.v){if(v>100)throw new Error(\"Cycle detected\");!function(i){if(0!==s&&0===v)if(i.l!==e){i.l=e;c={S:i,v:i.v,i:i.i,o:c}}}(this);this.v=i;this.i++;d++;s++;try{for(var n=this.t;void 0!==n;n=n.x)n.t.N()}finally{t()}}}});function y(i,t){return new l(i,t)}function w(i){for(var t=i.s;void 0!==t;t=t.n)if(t.S.i!==t.i||!t.S.h()||t.S.i!==t.i)return!0;return!1}function _(i){for(var t=i.s;void 0!==t;t=t.n){var n=t.S.n;if(void 0!==n)t.r=n;t.S.n=t;t.i=-1;if(void 0===t.n){i.s=t;break}}}function b(i){var t=i.s,n=void 0;while(void 0!==t){var r=t.p;if(-1===t.i){t.S.U(t);if(void 0!==r)r.n=t.n;if(void 0!==t.n)t.n.p=r}else n=t;t.S.n=t.r;if(void 0!==t.r)t.r=void 0;t=r}i.s=n}function p(i,t){l.call(this,void 0);this.x=i;this.s=void 0;this.g=d-1;this.f=4;this.W=null==t?void 0:t.watched;this.Z=null==t?void 0:t.unwatched;this.name=null==t?void 0:t.name}p.prototype=new l;p.prototype.h=function(){this.f&=-3;if(1&this.f)return!1;if(32==(36&this.f))return!0;this.f&=-5;if(this.g===d)return!0;this.g=d;this.f|=1;if(this.i>0&&!w(this)){this.f&=-2;return!0}var i=r;try{_(this);r=this;var t=this.x();if(16&this.f||this.v!==t||0===this.i){this.v=t;this.f&=-17;this.i++}}catch(i){this.v=i;this.f|=16;this.i++}r=i;b(this);this.f&=-2;return!0};p.prototype.S=function(i){if(void 0===this.t){this.f|=36;for(var t=this.s;void 0!==t;t=t.n)t.S.S(t)}l.prototype.S.call(this,i)};p.prototype.U=function(i){if(void 0!==this.t){l.prototype.U.call(this,i);if(void 0===this.t){this.f&=-33;for(var t=this.s;void 0!==t;t=t.n)t.S.U(t)}}};p.prototype.N=function(){if(!(2&this.f)){this.f|=6;for(var i=this.t;void 0!==i;i=i.x)i.t.N()}};Object.defineProperty(p.prototype,\"value\",{get:function(){if(1&this.f)throw new Error(\"Cycle detected\");var i=a(this);this.h();if(void 0!==i)i.i=this.i;if(16&this.f)throw this.v;return this.v}});function g(i,t){return new p(i,t)}function S(i){var n=i.m;i.m=void 0;if(\"function\"==typeof n){s++;var o=r;r=void 0;try{n()}catch(t){i.f&=-2;i.f|=8;m(i);throw t}finally{r=o;t()}}}function m(i){for(var t=i.s;void 0!==t;t=t.n)t.S.U(t);i.x=void 0;i.s=void 0;S(i)}function x(i){if(r!==this)throw new Error(\"Out-of-order effect\");b(this);r=i;this.f&=-2;if(8&this.f)m(this);t()}function E(i,t){this.x=i;this.m=void 0;this.s=void 0;this.u=void 0;this.f=32;this.name=null==t?void 0:t.name;if(f)f.push(this)}E.prototype.c=function(){var i=this.S();try{if(8&this.f)return;if(void 0===this.x)return;var t=this.x();if(\"function\"==typeof t)this.m=t}finally{i()}};E.prototype.S=function(){if(1&this.f)throw new Error(\"Cycle detected\");this.f|=1;this.f&=-9;S(this);_(this);s++;var i=r;r=this;return x.bind(this,i)};E.prototype.N=function(){if(!(2&this.f)){this.f|=2;this.u=h;h=this}};E.prototype.d=function(){this.f|=8;if(!(1&this.f))m(this)};E.prototype.dispose=function(){this.d()};function j(i,t){var n=new E(i,t);try{n.c()}catch(i){n.d();throw i}var r=n.d.bind(n);r[Symbol.dispose]=r;return r}function C(i){return function(){var t=arguments,r=this;return n(function(){return o(function(){return i.apply(r,[].slice.call(t))})})}}function O(){var i=f;f=[];return function(){var t=f;if(f&&i)i=i.concat(f);f=i;return t}}var k=function(i){for(var t in i){var n=i[t];if(\"function\"==typeof n)i[t]=C(n);else if(\"object\"==typeof n&&null!==n&&!(\"brand\"in n))k(n)}};function T(i){return function(){var t,n,r=O();try{n=i.apply(void 0,[].slice.call(arguments))}catch(i){f=void 0;throw i}finally{t=r()}k(n);n[Symbol.dispose]=C(function(){if(t)for(var i=0;i<t.length;i++)t[i].dispose();t=void 0});return n}}export{p as Computed,E as Effect,l as Signal,C as action,n as batch,g as computed,T as createModel,j as effect,y as signal,o as untracked};//# sourceMappingURL=signals-core.module.js.map\n",
|
|
@@ -8,6 +8,6 @@
|
|
|
8
8
|
"/**\n * Route pattern matcher\n * Supports:\n * - Exact match: 'POST /todos'\n * - Param match: 'GET /todos/:id'\n * - Wildcard: '/todos/*'\n */\nexport function matchRoute(pattern: string, method: string, path: string): boolean {\n const spaceIdx = pattern.indexOf(\" \");\n const patternMethod = spaceIdx === -1 ? null : pattern.slice(0, spaceIdx);\n const patternPath = spaceIdx === -1 ? pattern : pattern.slice(spaceIdx + 1);\n\n if (patternMethod && patternMethod !== method) {\n return false;\n }\n\n const patternSegments = patternPath.split(\"/\").filter(Boolean);\n const pathSegments = path.split(\"/\").filter(Boolean);\n\n if (patternSegments.length !== pathSegments.length && !patternPath.includes(\"*\")) {\n return false;\n }\n\n for (let i = 0; i < patternSegments.length; i++) {\n const patternSeg = patternSegments[i];\n const pathSeg = pathSegments[i];\n\n if (patternSeg === \"*\") return true;\n if (patternSeg?.startsWith(\":\")) continue;\n if (patternSeg !== pathSeg) return false;\n }\n\n return true;\n}\n\nexport function findMatchingConfig<T>(\n configs: Record<string, T> | undefined,\n method: string,\n path: string\n): T | undefined {\n if (!configs) return undefined;\n\n for (const [pattern, config] of Object.entries(configs)) {\n if (matchRoute(pattern, method, path)) {\n return config;\n }\n }\n\n return undefined;\n}\n"
|
|
9
9
|
],
|
|
10
10
|
"mappings": "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",
|
|
11
|
-
"debugId": "
|
|
11
|
+
"debugId": "74C4CA57821ED6F364756E2164756E21",
|
|
12
12
|
"names": []
|
|
13
13
|
}
|
|
@@ -23,6 +23,10 @@ type BaseButtonProps = {
|
|
|
23
23
|
disabled?: boolean;
|
|
24
24
|
fullWidth?: boolean;
|
|
25
25
|
circle?: boolean;
|
|
26
|
+
/** Cap the button width at `--polly-control-max-width` and ellipsis-
|
|
27
|
+
* truncate the label. Use for user-supplied or otherwise unbounded
|
|
28
|
+
* labels so a long string doesn't blow out the row. */
|
|
29
|
+
bounded?: boolean;
|
|
26
30
|
className?: string;
|
|
27
31
|
title?: string;
|
|
28
32
|
icon?: VNode;
|
|
@@ -70,6 +70,8 @@
|
|
|
70
70
|
position: fixed;
|
|
71
71
|
inset: unset;
|
|
72
72
|
z-index: var(--polly-z-raised);
|
|
73
|
+
min-width: var(--polly-menu-min-width);
|
|
74
|
+
max-width: var(--polly-menu-max-width);
|
|
73
75
|
padding: var(--polly-space-xs) 0;
|
|
74
76
|
border: var(--polly-border-width-default) solid var(--polly-border);
|
|
75
77
|
border-radius: var(--polly-radius-md);
|
|
@@ -77,7 +79,6 @@
|
|
|
77
79
|
box-shadow: var(--polly-shadow-md);
|
|
78
80
|
box-sizing: border-box;
|
|
79
81
|
overflow-y: auto;
|
|
80
|
-
min-width: 160px;
|
|
81
82
|
max-height: 280px;
|
|
82
83
|
margin: 0;
|
|
83
84
|
}
|
|
@@ -159,6 +160,7 @@
|
|
|
159
160
|
display: inline-flex;
|
|
160
161
|
align-items: center;
|
|
161
162
|
gap: var(--polly-space-sm);
|
|
163
|
+
max-width: min(100%, var(--polly-control-max-width));
|
|
162
164
|
padding: var(--polly-space-sm) var(--polly-space-md);
|
|
163
165
|
border: var(--polly-border-width-default) solid var(--polly-border);
|
|
164
166
|
border-radius: var(--polly-radius-sm);
|
|
@@ -166,9 +168,8 @@
|
|
|
166
168
|
font-family: inherit;
|
|
167
169
|
font-size: var(--polly-text-md);
|
|
168
170
|
color: var(--polly-text);
|
|
169
|
-
text-align:
|
|
171
|
+
text-align: start;
|
|
170
172
|
cursor: pointer;
|
|
171
|
-
max-width: 100%;
|
|
172
173
|
}
|
|
173
174
|
|
|
174
175
|
.trigger_daofbw:disabled, .trigger_daofbw[aria-disabled="true"] {
|
|
@@ -177,7 +178,7 @@
|
|
|
177
178
|
}
|
|
178
179
|
|
|
179
180
|
.triggerWide_daofbw {
|
|
180
|
-
min-width:
|
|
181
|
+
min-width: var(--polly-control-min-width-md);
|
|
181
182
|
}
|
|
182
183
|
|
|
183
184
|
.triggerLabel_daofbw {
|
|
@@ -239,8 +240,11 @@
|
|
|
239
240
|
font-family: inherit;
|
|
240
241
|
font-size: var(--polly-text-sm);
|
|
241
242
|
color: var(--polly-text);
|
|
242
|
-
text-align:
|
|
243
|
+
text-align: start;
|
|
243
244
|
cursor: pointer;
|
|
245
|
+
white-space: nowrap;
|
|
246
|
+
overflow: hidden;
|
|
247
|
+
text-overflow: ellipsis;
|
|
244
248
|
background: none;
|
|
245
249
|
border: none;
|
|
246
250
|
width: 100%;
|
|
@@ -256,9 +260,9 @@
|
|
|
256
260
|
|
|
257
261
|
.optionCheck_daofbw {
|
|
258
262
|
accent-color: var(--polly-accent);
|
|
259
|
-
margin-right: var(--polly-space-sm);
|
|
260
263
|
vertical-align: middle;
|
|
261
264
|
pointer-events: none;
|
|
265
|
+
margin-inline-end: var(--polly-space-sm);
|
|
262
266
|
}
|
|
263
267
|
}
|
|
264
268
|
|
|
@@ -408,6 +412,13 @@
|
|
|
408
412
|
.btnFullWidth_c4HKfA {
|
|
409
413
|
width: 100%;
|
|
410
414
|
}
|
|
415
|
+
|
|
416
|
+
.btnBounded_c4HKfA {
|
|
417
|
+
max-width: var(--polly-control-max-width);
|
|
418
|
+
overflow: hidden;
|
|
419
|
+
text-overflow: ellipsis;
|
|
420
|
+
white-space: nowrap;
|
|
421
|
+
}
|
|
411
422
|
}
|
|
412
423
|
|
|
413
424
|
/* src/polly-ui/Surface.module.css */
|
|
@@ -512,8 +523,8 @@
|
|
|
512
523
|
}
|
|
513
524
|
|
|
514
525
|
.label_EKE5sg {
|
|
515
|
-
margin-left: var(--polly-space-sm);
|
|
516
526
|
vertical-align: middle;
|
|
527
|
+
margin-inline-start: var(--polly-space-sm);
|
|
517
528
|
}
|
|
518
529
|
}
|
|
519
530
|
|
|
@@ -593,15 +604,23 @@
|
|
|
593
604
|
.summary_sEhnPw:before {
|
|
594
605
|
content: "▶";
|
|
595
606
|
display: inline-block;
|
|
596
|
-
margin-right: var(--polly-space-sm);
|
|
597
607
|
font-size: var(--polly-text-xs);
|
|
598
608
|
transition: transform var(--polly-motion-fast);
|
|
609
|
+
margin-inline-end: var(--polly-space-sm);
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
[dir="rtl"] .summary_sEhnPw:before {
|
|
613
|
+
transform: scaleX(-1);
|
|
599
614
|
}
|
|
600
615
|
|
|
601
616
|
.collapsible_sEhnPw[open] > .summary_sEhnPw:before {
|
|
602
617
|
transform: rotate(90deg);
|
|
603
618
|
}
|
|
604
619
|
|
|
620
|
+
[dir="rtl"] .collapsible_sEhnPw[open] > .summary_sEhnPw:before {
|
|
621
|
+
transform: rotate(-90deg);
|
|
622
|
+
}
|
|
623
|
+
|
|
605
624
|
.summary_sEhnPw:hover {
|
|
606
625
|
background-color: var(--polly-surface-raised);
|
|
607
626
|
}
|
|
@@ -1118,12 +1137,21 @@
|
|
|
1118
1137
|
left: 2px;
|
|
1119
1138
|
}
|
|
1120
1139
|
|
|
1140
|
+
[dir="rtl"] .thumb_rnf-SQ {
|
|
1141
|
+
left: auto;
|
|
1142
|
+
right: 2px;
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1121
1145
|
.thumbChecked_rnf-SQ {
|
|
1122
1146
|
transform: translateX(16px);
|
|
1123
1147
|
}
|
|
1124
1148
|
|
|
1149
|
+
[dir="rtl"] .thumbChecked_rnf-SQ {
|
|
1150
|
+
transform: translateX(-16px);
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1125
1153
|
.label_rnf-SQ {
|
|
1126
|
-
margin-left: var(--polly-space-sm);
|
|
1127
1154
|
vertical-align: middle;
|
|
1155
|
+
margin-inline-start: var(--polly-space-sm);
|
|
1128
1156
|
}
|
|
1129
1157
|
}
|
|
@@ -445,7 +445,9 @@ function Dropdown(props) {
|
|
|
445
445
|
menu.style.display = prevDisplay;
|
|
446
446
|
const viewportWidth = document.documentElement.clientWidth;
|
|
447
447
|
const viewportHeight = document.documentElement.clientHeight;
|
|
448
|
-
|
|
448
|
+
const isRtl = getComputedStyle(trigger2).direction === "rtl" || document.documentElement.dir === "rtl";
|
|
449
|
+
const physicalRight = isRtl && align === "left" || align === "right";
|
|
450
|
+
let left = physicalRight ? t.right - menuWidth : t.left;
|
|
449
451
|
const maxLeft = Math.max(VIEWPORT_PADDING, viewportWidth - menuWidth - VIEWPORT_PADDING);
|
|
450
452
|
left = Math.min(Math.max(left, VIEWPORT_PADDING), maxLeft);
|
|
451
453
|
const spaceBelow = viewportHeight - t.bottom - MENU_GAP - VIEWPORT_PADDING;
|
|
@@ -707,7 +709,8 @@ var Button_module_default = {
|
|
|
707
709
|
btnSmall: "btnSmall_c4HKfA",
|
|
708
710
|
btnLarge: "btnLarge_c4HKfA",
|
|
709
711
|
btnCircle: "btnCircle_c4HKfA",
|
|
710
|
-
btnFullWidth: "btnFullWidth_c4HKfA"
|
|
712
|
+
btnFullWidth: "btnFullWidth_c4HKfA",
|
|
713
|
+
btnBounded: "btnBounded_c4HKfA"
|
|
711
714
|
};
|
|
712
715
|
|
|
713
716
|
// src/polly-ui/Button.tsx
|
|
@@ -746,6 +749,7 @@ function Button(props) {
|
|
|
746
749
|
disabled = false,
|
|
747
750
|
fullWidth = false,
|
|
748
751
|
circle = false,
|
|
752
|
+
bounded = false,
|
|
749
753
|
className,
|
|
750
754
|
title,
|
|
751
755
|
icon,
|
|
@@ -765,6 +769,8 @@ function Button(props) {
|
|
|
765
769
|
parts.push(Button_module_default["btnCircle"] ?? "");
|
|
766
770
|
if (fullWidth)
|
|
767
771
|
parts.push(Button_module_default["btnFullWidth"] ?? "");
|
|
772
|
+
if (bounded)
|
|
773
|
+
parts.push(Button_module_default["btnBounded"] ?? "");
|
|
768
774
|
if (className)
|
|
769
775
|
parts.push(className);
|
|
770
776
|
const buttonClass = parts.filter(Boolean).join(" ");
|
|
@@ -1775,9 +1781,13 @@ function Output(props) {
|
|
|
1775
1781
|
// src/polly-ui/Select.tsx
|
|
1776
1782
|
import { useComputed, useSignal as useSignal2 } from "@preact/signals";
|
|
1777
1783
|
import { jsxDEV as jsxDEV17, Fragment as Fragment2 } from "preact/jsx-dev-runtime";
|
|
1778
|
-
|
|
1784
|
+
var MULTI_SELECT_LABEL_THRESHOLD = 2;
|
|
1785
|
+
function formatSelected(options, selected, multiSelect) {
|
|
1779
1786
|
if (selected.size === 0)
|
|
1780
1787
|
return "";
|
|
1788
|
+
if (multiSelect && selected.size > MULTI_SELECT_LABEL_THRESHOLD) {
|
|
1789
|
+
return `${selected.size} selected`;
|
|
1790
|
+
}
|
|
1781
1791
|
const labels = [];
|
|
1782
1792
|
for (const opt of options) {
|
|
1783
1793
|
if (selected.has(opt.value))
|
|
@@ -1799,7 +1809,7 @@ function Select(props) {
|
|
|
1799
1809
|
} = props;
|
|
1800
1810
|
const isOpen2 = useSignal2(false);
|
|
1801
1811
|
const displayText = useComputed(() => {
|
|
1802
|
-
const text = formatSelected(options, selected.value);
|
|
1812
|
+
const text = formatSelected(options, selected.value, multiSelect);
|
|
1803
1813
|
return text.length > 0 ? text : placeholder;
|
|
1804
1814
|
});
|
|
1805
1815
|
const isEmpty = useComputed(() => selected.value.size === 0);
|
|
@@ -2325,4 +2335,4 @@ export {
|
|
|
2325
2335
|
ActionForm
|
|
2326
2336
|
};
|
|
2327
2337
|
|
|
2328
|
-
//# debugId=
|
|
2338
|
+
//# debugId=E9957371E8115C1E64756E2164756E21
|