@getforma/core 1.0.6 → 1.0.8

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.
Files changed (50) hide show
  1. package/README.md +4 -4
  2. package/dist/{chunk-V732ZBCU.cjs → chunk-7L3KHGEA.cjs} +95 -50
  3. package/dist/chunk-7L3KHGEA.cjs.map +1 -0
  4. package/dist/{chunk-VTPFK5TJ.js → chunk-7Q7LIV23.js} +59 -14
  5. package/dist/chunk-7Q7LIV23.js.map +1 -0
  6. package/dist/{chunk-DCTOXHPF.cjs → chunk-BARF67I6.cjs} +8 -8
  7. package/dist/chunk-BARF67I6.cjs.map +1 -0
  8. package/dist/{chunk-OZCHIVAZ.js → chunk-HLM5BZZQ.js} +2 -2
  9. package/dist/chunk-HLM5BZZQ.js.map +1 -0
  10. package/dist/{chunk-3U57L2TY.cjs → chunk-QLPCVK7C.cjs} +2 -2
  11. package/dist/chunk-QLPCVK7C.cjs.map +1 -0
  12. package/dist/{chunk-OUVOAYIO.js → chunk-TBWZZ3SI.js} +3 -3
  13. package/dist/chunk-TBWZZ3SI.js.map +1 -0
  14. package/dist/formajs-runtime-hardened.global.js.map +1 -1
  15. package/dist/formajs-runtime.global.js.map +1 -1
  16. package/dist/formajs.global.js +55 -10
  17. package/dist/formajs.global.js.map +1 -1
  18. package/dist/http.cjs +13 -13
  19. package/dist/http.cjs.map +1 -1
  20. package/dist/http.js +4 -4
  21. package/dist/http.js.map +1 -1
  22. package/dist/index.cjs +61 -61
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.d.cts +141 -10
  25. package/dist/index.d.ts +141 -10
  26. package/dist/index.js +6 -6
  27. package/dist/index.js.map +1 -1
  28. package/dist/{resource-Cd0cGOxS.d.ts → resource-BHsgURy0.d.ts} +3 -1
  29. package/dist/{resource-DK98lW5e.d.cts → resource-DeEzxUz6.d.cts} +3 -1
  30. package/dist/runtime-hardened.cjs.map +1 -1
  31. package/dist/runtime-hardened.js.map +1 -1
  32. package/dist/runtime.cjs +29 -29
  33. package/dist/runtime.js +3 -3
  34. package/dist/server.cjs +7 -7
  35. package/dist/server.d.cts +2 -2
  36. package/dist/server.d.ts +2 -2
  37. package/dist/server.js +2 -2
  38. package/dist/{signal-YlS1kgfh.d.cts → signal-C9v4akyJ.d.cts} +2 -0
  39. package/dist/{signal-YlS1kgfh.d.ts → signal-C9v4akyJ.d.ts} +2 -0
  40. package/dist/tc39-compat.cjs +3 -3
  41. package/dist/tc39-compat.d.cts +1 -1
  42. package/dist/tc39-compat.d.ts +1 -1
  43. package/dist/tc39-compat.js +1 -1
  44. package/package.json +1 -1
  45. package/dist/chunk-3U57L2TY.cjs.map +0 -1
  46. package/dist/chunk-DCTOXHPF.cjs.map +0 -1
  47. package/dist/chunk-OUVOAYIO.js.map +0 -1
  48. package/dist/chunk-OZCHIVAZ.js.map +0 -1
  49. package/dist/chunk-V732ZBCU.cjs.map +0 -1
  50. package/dist/chunk-VTPFK5TJ.js.map +0 -1
package/dist/http.cjs CHANGED
@@ -1,13 +1,13 @@
1
1
  'use strict';
2
2
 
3
- var chunkDCTOXHPF_cjs = require('./chunk-DCTOXHPF.cjs');
4
- var chunk3U57L2TY_cjs = require('./chunk-3U57L2TY.cjs');
3
+ var chunkBARF67I6_cjs = require('./chunk-BARF67I6.cjs');
4
+ var chunkQLPCVK7C_cjs = require('./chunk-QLPCVK7C.cjs');
5
5
 
6
6
  // src/http/fetch.ts
7
7
  function createFetch(url, options) {
8
- const [data, setData] = chunk3U57L2TY_cjs.createSignal(null);
9
- const [error, setError] = chunk3U57L2TY_cjs.createSignal(null);
10
- const [loading, setLoading] = chunk3U57L2TY_cjs.createSignal(false);
8
+ const [data, setData] = chunkQLPCVK7C_cjs.createSignal(null);
9
+ const [error, setError] = chunkQLPCVK7C_cjs.createSignal(null);
10
+ const [loading, setLoading] = chunkQLPCVK7C_cjs.createSignal(false);
11
11
  let currentController = null;
12
12
  function resolveURL() {
13
13
  const raw = typeof url === "function" ? url() : url;
@@ -57,12 +57,12 @@ function createFetch(url, options) {
57
57
  }
58
58
  }
59
59
  if (typeof url === "function") {
60
- chunkDCTOXHPF_cjs.internalEffect(() => {
60
+ chunkBARF67I6_cjs.internalEffect(() => {
61
61
  url();
62
- execute();
62
+ void execute();
63
63
  });
64
64
  } else {
65
- execute();
65
+ void execute();
66
66
  }
67
67
  return {
68
68
  data,
@@ -86,9 +86,9 @@ async function fetchJSON(url, options) {
86
86
 
87
87
  // src/http/sse.ts
88
88
  function createSSE(url, options) {
89
- const [data, setData] = chunk3U57L2TY_cjs.createSignal(null);
90
- const [error, setError] = chunk3U57L2TY_cjs.createSignal(null);
91
- const [connected, setConnected] = chunk3U57L2TY_cjs.createSignal(false);
89
+ const [data, setData] = chunkQLPCVK7C_cjs.createSignal(null);
90
+ const [error, setError] = chunkQLPCVK7C_cjs.createSignal(null);
91
+ const [connected, setConnected] = chunkQLPCVK7C_cjs.createSignal(false);
92
92
  const source = new EventSource(url, {
93
93
  withCredentials: options?.withCredentials ?? false
94
94
  });
@@ -142,8 +142,8 @@ function createWebSocket(url, options) {
142
142
  const shouldReconnect = options?.reconnect ?? true;
143
143
  const baseInterval = options?.reconnectInterval ?? 1e3;
144
144
  const maxReconnects = options?.maxReconnects ?? 5;
145
- const [data, setData] = chunk3U57L2TY_cjs.createSignal(null);
146
- const [status, setStatus] = chunk3U57L2TY_cjs.createSignal("connecting");
145
+ const [data, setData] = chunkQLPCVK7C_cjs.createSignal(null);
146
+ const [status, setStatus] = chunkQLPCVK7C_cjs.createSignal("connecting");
147
147
  const handlers = /* @__PURE__ */ new Set();
148
148
  let socket = null;
149
149
  let reconnectCount = 0;
package/dist/http.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/http/fetch.ts","../src/http/sse.ts","../src/http/ws.ts"],"names":["createSignal","internalEffect"],"mappings":"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","file":"http.cjs","sourcesContent":["/**\n * Forma HTTP - Fetch\n *\n * Typed fetch wrapper with reactive signal integration.\n * Zero dependencies — native browser APIs only.\n */\n\nimport { createSignal, internalEffect } from 'forma/reactive';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface FetchOptions<T> extends Omit<RequestInit, 'signal'> {\n base?: string;\n params?: Record<string, string>;\n timeout?: number; // ms, default 30000\n transform?: (data: unknown) => T;\n}\n\nexport interface FetchResult<T> {\n data: () => T | null;\n error: () => Error | null;\n loading: () => boolean;\n refetch: () => Promise<void>;\n abort: () => void;\n}\n\n// ---------------------------------------------------------------------------\n// createFetch — reactive fetch with signals\n// ---------------------------------------------------------------------------\n\n/**\n * Create a reactive fetch that exposes data/error/loading as signals.\n *\n * If `url` is a signal getter (function), an effect auto-refetches when it\n * changes.\n *\n * ```ts\n * const { data, loading, error, refetch, abort } = createFetch<User[]>('/api/users');\n * ```\n */\nexport function createFetch<T>(\n url: string | (() => string),\n options?: FetchOptions<T>,\n): FetchResult<T> {\n const [data, setData] = createSignal<T | null>(null);\n const [error, setError] = createSignal<Error | null>(null);\n const [loading, setLoading] = createSignal<boolean>(false);\n\n let currentController: AbortController | null = null;\n\n /** Resolve the URL string, applying base and params. */\n function resolveURL(): string {\n const raw = typeof url === 'function' ? url() : url;\n const base = options?.base || (typeof window !== 'undefined' ? window.location.origin : '');\n const fullURL = new URL(raw, base || undefined);\n\n if (options?.params) {\n for (const [key, value] of Object.entries(options.params)) {\n fullURL.searchParams.set(key, value);\n }\n }\n\n return fullURL.toString();\n }\n\n /** Execute a single fetch request. */\n async function execute(): Promise<void> {\n // Abort any in-flight request\n if (currentController) {\n currentController.abort();\n }\n\n currentController = new AbortController();\n const controller = currentController;\n const timeoutMs = options?.timeout ?? 30_000;\n\n // Set up timeout\n const timeoutId = setTimeout(() => controller.abort(), timeoutMs);\n\n setLoading(true);\n setError(null);\n\n try {\n const resolvedURL = resolveURL();\n\n const { base: _base, params: _params, timeout: _timeout, transform, ...fetchInit } =\n options ?? {};\n\n const response = await fetch(resolvedURL, {\n ...fetchInit,\n signal: controller.signal,\n });\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n const json: unknown = await response.json();\n const transformed = transform ? transform(json) : (json as T);\n setData(transformed);\n } catch (err) {\n if (err instanceof Error && err.name === 'AbortError') {\n // Ignore aborts — they are intentional or timeouts\n return;\n }\n setError(err instanceof Error ? err : new Error(String(err)));\n } finally {\n clearTimeout(timeoutId);\n // Only update loading if this controller is still current\n if (currentController === controller) {\n currentController = null;\n setLoading(false);\n }\n }\n }\n\n // If url is a reactive getter, set up an effect to auto-refetch.\n if (typeof url === 'function') {\n internalEffect(() => {\n // Read the signal so the effect re-runs when it changes\n url();\n execute();\n });\n } else {\n // Kick off the first request immediately\n execute();\n }\n\n return {\n data,\n error,\n loading,\n refetch: execute,\n abort() {\n if (currentController) {\n currentController.abort();\n }\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// fetchJSON — simple one-shot helper\n// ---------------------------------------------------------------------------\n\n/**\n * One-shot fetch that returns parsed JSON.\n *\n * ```ts\n * const users = await fetchJSON<User[]>('/api/users');\n * ```\n */\nexport async function fetchJSON<T>(url: string, options?: RequestInit): Promise<T> {\n const response = await fetch(url, options);\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n return (await response.json()) as T;\n}\n","/**\n * Forma HTTP - Server-Sent Events\n *\n * Reactive SSE wrapper with signal integration.\n * Zero dependencies — native browser APIs only.\n */\n\nimport { createSignal } from 'forma/reactive';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface SSEOptions<T = unknown> {\n withCredentials?: boolean;\n headers?: Record<string, string>; // Note: native EventSource does not support custom headers\n /** Custom parser for incoming messages. Defaults to JSON.parse with raw data fallback. */\n parse?: (data: string) => T;\n}\n\nexport interface SSEConnection<T = unknown> {\n data: () => T | null;\n error: () => Event | null;\n connected: () => boolean;\n close: () => void;\n on(event: string, handler: (data: unknown) => void): () => void;\n}\n\n// ---------------------------------------------------------------------------\n// createSSE\n// ---------------------------------------------------------------------------\n\n/**\n * Create a reactive Server-Sent Events connection.\n *\n * ```ts\n * const sse = createSSE<{ message: string }>('/api/events');\n * createEffect(() => {\n * const msg = sse.data();\n * if (msg) console.log(msg.message);\n * });\n * ```\n */\nexport function createSSE<T = unknown>(\n url: string,\n options?: SSEOptions<T>,\n): SSEConnection<T> {\n const [data, setData] = createSignal<T | null>(null);\n const [error, setError] = createSignal<Event | null>(null);\n const [connected, setConnected] = createSignal<boolean>(false);\n\n const source = new EventSource(url, {\n withCredentials: options?.withCredentials ?? false,\n });\n\n source.onopen = () => {\n setConnected(true);\n setError(null);\n };\n\n const parseMessage = options?.parse ?? ((raw: string): T => {\n try { return JSON.parse(raw) as T; }\n catch { return raw as T; }\n });\n\n source.onmessage = (event: MessageEvent) => {\n setData(parseMessage(event.data as string));\n };\n\n source.onerror = (event: Event) => {\n setError(event);\n setConnected(false);\n };\n\n return {\n data,\n error,\n connected,\n\n close(): void {\n source.close();\n setConnected(false);\n },\n\n on(event: string, handler: (data: unknown) => void): () => void {\n const parseEvent = options?.parse ?? ((raw: string) => {\n try { return JSON.parse(raw); }\n catch { return raw; }\n });\n const listener = (e: MessageEvent) => {\n handler(parseEvent(e.data as string));\n };\n source.addEventListener(event, listener as EventListener);\n return () => {\n source.removeEventListener(event, listener as EventListener);\n };\n },\n };\n}\n","/**\n * Forma HTTP - WebSocket\n *\n * Reactive WebSocket wrapper with auto-reconnect and signal integration.\n * Zero dependencies — native browser APIs only.\n */\n\nimport { createSignal } from 'forma/reactive';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type WSStatus = 'connecting' | 'open' | 'closed' | 'error';\n\nexport interface WSOptions<TReceive = unknown> {\n protocols?: string | string[];\n reconnect?: boolean; // default true\n reconnectInterval?: number; // ms, default 1000\n maxReconnects?: number; // default 5\n /** Custom parser for incoming messages. Defaults to JSON.parse with raw data fallback. */\n parse?: (data: string) => TReceive;\n}\n\nexport interface WSConnection<TSend = unknown, TReceive = unknown> {\n data: () => TReceive | null;\n status: () => WSStatus;\n send(data: TSend): void;\n close(): void;\n on(handler: (data: TReceive) => void): () => void;\n}\n\n// ---------------------------------------------------------------------------\n// createWebSocket\n// ---------------------------------------------------------------------------\n\n/**\n * Create a reactive WebSocket connection with auto-reconnect.\n *\n * ```ts\n * const ws = createWebSocket<string, ChatMessage>('wss://chat.example.com');\n * ws.send('hello');\n * createEffect(() => {\n * const msg = ws.data();\n * if (msg) console.log(msg);\n * });\n * ```\n */\nexport function createWebSocket<TSend = unknown, TReceive = unknown>(\n url: string,\n options?: WSOptions<TReceive>,\n): WSConnection<TSend, TReceive> {\n const shouldReconnect = options?.reconnect ?? true;\n const baseInterval = options?.reconnectInterval ?? 1000;\n const maxReconnects = options?.maxReconnects ?? 5;\n\n const [data, setData] = createSignal<TReceive | null>(null);\n const [status, setStatus] = createSignal<WSStatus>('connecting');\n\n const handlers = new Set<(data: TReceive) => void>();\n\n let socket: WebSocket | null = null;\n let reconnectCount = 0;\n let reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n let permanentlyClosed = false;\n\n function connect(): void {\n if (permanentlyClosed) return;\n\n setStatus('connecting');\n socket = new WebSocket(url, options?.protocols);\n\n socket.onopen = () => {\n setStatus('open');\n reconnectCount = 0; // Reset on successful connection\n };\n\n const parseMessage = options?.parse ?? ((raw: string): TReceive => {\n try { return JSON.parse(raw) as TReceive; }\n catch { return raw as TReceive; }\n });\n\n socket.onmessage = (event: MessageEvent) => {\n const parsed = parseMessage(event.data as string);\n setData(parsed);\n for (const handler of handlers) {\n handler(parsed);\n }\n };\n\n socket.onerror = () => {\n setStatus('error');\n };\n\n socket.onclose = () => {\n if (permanentlyClosed) {\n setStatus('closed');\n return;\n }\n\n setStatus('closed');\n\n if (shouldReconnect && reconnectCount < maxReconnects) {\n // Exponential backoff: baseInterval * 2^reconnectCount\n const delay = baseInterval * Math.pow(2, reconnectCount);\n reconnectCount++;\n reconnectTimer = setTimeout(connect, delay);\n }\n };\n }\n\n // Initiate the first connection\n connect();\n\n return {\n data,\n status,\n\n send(value: TSend): void {\n if (socket && socket.readyState === WebSocket.OPEN) {\n socket.send(JSON.stringify(value));\n }\n },\n\n close(): void {\n permanentlyClosed = true;\n if (reconnectTimer !== null) {\n clearTimeout(reconnectTimer);\n reconnectTimer = null;\n }\n if (socket) {\n socket.close();\n socket = null;\n }\n setStatus('closed');\n },\n\n on(handler: (data: TReceive) => void): () => void {\n handlers.add(handler);\n return () => {\n handlers.delete(handler);\n };\n },\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/http/fetch.ts","../src/http/sse.ts","../src/http/ws.ts"],"names":["createSignal","internalEffect"],"mappings":"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","file":"http.cjs","sourcesContent":["/**\n * Forma HTTP - Fetch\n *\n * Typed fetch wrapper with reactive signal integration.\n * Zero dependencies — native browser APIs only.\n */\n\nimport { createSignal, internalEffect } from 'forma/reactive';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface FetchOptions<T> extends Omit<RequestInit, 'signal'> {\n base?: string;\n params?: Record<string, string>;\n timeout?: number; // ms, default 30000\n transform?: (data: unknown) => T;\n}\n\nexport interface FetchResult<T> {\n data: () => T | null;\n error: () => Error | null;\n loading: () => boolean;\n refetch: () => Promise<void>;\n abort: () => void;\n}\n\n// ---------------------------------------------------------------------------\n// createFetch — reactive fetch with signals\n// ---------------------------------------------------------------------------\n\n/**\n * Create a reactive fetch that exposes data/error/loading as signals.\n *\n * If `url` is a signal getter (function), an effect auto-refetches when it\n * changes.\n *\n * ```ts\n * const { data, loading, error, refetch, abort } = createFetch<User[]>('/api/users');\n * ```\n */\nexport function createFetch<T>(\n url: string | (() => string),\n options?: FetchOptions<T>,\n): FetchResult<T> {\n const [data, setData] = createSignal<T | null>(null);\n const [error, setError] = createSignal<Error | null>(null);\n const [loading, setLoading] = createSignal<boolean>(false);\n\n let currentController: AbortController | null = null;\n\n /** Resolve the URL string, applying base and params. */\n function resolveURL(): string {\n const raw = typeof url === 'function' ? url() : url;\n const base = options?.base || (typeof window !== 'undefined' ? window.location.origin : '');\n const fullURL = new URL(raw, base || undefined);\n\n if (options?.params) {\n for (const [key, value] of Object.entries(options.params)) {\n fullURL.searchParams.set(key, value);\n }\n }\n\n return fullURL.toString();\n }\n\n /** Execute a single fetch request. */\n async function execute(): Promise<void> {\n // Abort any in-flight request\n if (currentController) {\n currentController.abort();\n }\n\n currentController = new AbortController();\n const controller = currentController;\n const timeoutMs = options?.timeout ?? 30_000;\n\n // Set up timeout\n const timeoutId = setTimeout(() => controller.abort(), timeoutMs);\n\n setLoading(true);\n setError(null);\n\n try {\n const resolvedURL = resolveURL();\n\n const { base: _base, params: _params, timeout: _timeout, transform, ...fetchInit } =\n options ?? {};\n\n const response = await fetch(resolvedURL, {\n ...fetchInit,\n signal: controller.signal,\n });\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n const json: unknown = await response.json();\n const transformed = transform ? transform(json) : (json as T);\n setData(transformed);\n } catch (err) {\n if (err instanceof Error && err.name === 'AbortError') {\n // Ignore aborts — they are intentional or timeouts\n return;\n }\n setError(err instanceof Error ? err : new Error(String(err)));\n } finally {\n clearTimeout(timeoutId);\n // Only update loading if this controller is still current\n if (currentController === controller) {\n currentController = null;\n setLoading(false);\n }\n }\n }\n\n // If url is a reactive getter, set up an effect to auto-refetch.\n if (typeof url === 'function') {\n internalEffect(() => {\n // Read the signal so the effect re-runs when it changes\n url();\n void execute();\n });\n } else {\n // Kick off the first request immediately\n void execute();\n }\n\n return {\n data,\n error,\n loading,\n refetch: execute,\n abort() {\n if (currentController) {\n currentController.abort();\n }\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// fetchJSON — simple one-shot helper\n// ---------------------------------------------------------------------------\n\n/**\n * One-shot fetch that returns parsed JSON.\n *\n * ```ts\n * const users = await fetchJSON<User[]>('/api/users');\n * ```\n */\nexport async function fetchJSON<T>(url: string, options?: RequestInit): Promise<T> {\n const response = await fetch(url, options);\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n return (await response.json()) as T;\n}\n","/**\n * Forma HTTP - Server-Sent Events\n *\n * Reactive SSE wrapper with signal integration.\n * Zero dependencies — native browser APIs only.\n */\n\nimport { createSignal } from 'forma/reactive';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface SSEOptions<T = unknown> {\n withCredentials?: boolean;\n headers?: Record<string, string>; // Note: native EventSource does not support custom headers\n /** Custom parser for incoming messages. Defaults to JSON.parse with raw data fallback. */\n parse?: (data: string) => T;\n}\n\nexport interface SSEConnection<T = unknown> {\n data: () => T | null;\n error: () => Event | null;\n connected: () => boolean;\n close: () => void;\n on(event: string, handler: (data: unknown) => void): () => void;\n}\n\n// ---------------------------------------------------------------------------\n// createSSE\n// ---------------------------------------------------------------------------\n\n/**\n * Create a reactive Server-Sent Events connection.\n *\n * ```ts\n * const sse = createSSE<{ message: string }>('/api/events');\n * createEffect(() => {\n * const msg = sse.data();\n * if (msg) console.log(msg.message);\n * });\n * ```\n */\nexport function createSSE<T = unknown>(\n url: string,\n options?: SSEOptions<T>,\n): SSEConnection<T> {\n const [data, setData] = createSignal<T | null>(null);\n const [error, setError] = createSignal<Event | null>(null);\n const [connected, setConnected] = createSignal<boolean>(false);\n\n const source = new EventSource(url, {\n withCredentials: options?.withCredentials ?? false,\n });\n\n source.onopen = () => {\n setConnected(true);\n setError(null);\n };\n\n const parseMessage = options?.parse ?? ((raw: string): T => {\n try { return JSON.parse(raw) as T; }\n catch { return raw as T; }\n });\n\n source.onmessage = (event: MessageEvent) => {\n setData(parseMessage(event.data as string));\n };\n\n source.onerror = (event: Event) => {\n setError(event);\n setConnected(false);\n };\n\n return {\n data,\n error,\n connected,\n\n close(): void {\n source.close();\n setConnected(false);\n },\n\n on(event: string, handler: (data: unknown) => void): () => void {\n const parseEvent = options?.parse ?? ((raw: string) => {\n try { return JSON.parse(raw); }\n catch { return raw; }\n });\n const listener = (e: MessageEvent) => {\n handler(parseEvent(e.data as string));\n };\n source.addEventListener(event, listener as EventListener);\n return () => {\n source.removeEventListener(event, listener as EventListener);\n };\n },\n };\n}\n","/**\n * Forma HTTP - WebSocket\n *\n * Reactive WebSocket wrapper with auto-reconnect and signal integration.\n * Zero dependencies — native browser APIs only.\n */\n\nimport { createSignal } from 'forma/reactive';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type WSStatus = 'connecting' | 'open' | 'closed' | 'error';\n\nexport interface WSOptions<TReceive = unknown> {\n protocols?: string | string[];\n reconnect?: boolean; // default true\n reconnectInterval?: number; // ms, default 1000\n maxReconnects?: number; // default 5\n /** Custom parser for incoming messages. Defaults to JSON.parse with raw data fallback. */\n parse?: (data: string) => TReceive;\n}\n\nexport interface WSConnection<TSend = unknown, TReceive = unknown> {\n data: () => TReceive | null;\n status: () => WSStatus;\n send(data: TSend): void;\n close(): void;\n on(handler: (data: TReceive) => void): () => void;\n}\n\n// ---------------------------------------------------------------------------\n// createWebSocket\n// ---------------------------------------------------------------------------\n\n/**\n * Create a reactive WebSocket connection with auto-reconnect.\n *\n * ```ts\n * const ws = createWebSocket<string, ChatMessage>('wss://chat.example.com');\n * ws.send('hello');\n * createEffect(() => {\n * const msg = ws.data();\n * if (msg) console.log(msg);\n * });\n * ```\n */\nexport function createWebSocket<TSend = unknown, TReceive = unknown>(\n url: string,\n options?: WSOptions<TReceive>,\n): WSConnection<TSend, TReceive> {\n const shouldReconnect = options?.reconnect ?? true;\n const baseInterval = options?.reconnectInterval ?? 1000;\n const maxReconnects = options?.maxReconnects ?? 5;\n\n const [data, setData] = createSignal<TReceive | null>(null);\n const [status, setStatus] = createSignal<WSStatus>('connecting');\n\n const handlers = new Set<(data: TReceive) => void>();\n\n let socket: WebSocket | null = null;\n let reconnectCount = 0;\n let reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n let permanentlyClosed = false;\n\n function connect(): void {\n if (permanentlyClosed) return;\n\n setStatus('connecting');\n socket = new WebSocket(url, options?.protocols);\n\n socket.onopen = () => {\n setStatus('open');\n reconnectCount = 0; // Reset on successful connection\n };\n\n const parseMessage = options?.parse ?? ((raw: string): TReceive => {\n try { return JSON.parse(raw) as TReceive; }\n catch { return raw as TReceive; }\n });\n\n socket.onmessage = (event: MessageEvent) => {\n const parsed = parseMessage(event.data as string);\n setData(parsed);\n for (const handler of handlers) {\n handler(parsed);\n }\n };\n\n socket.onerror = () => {\n setStatus('error');\n };\n\n socket.onclose = () => {\n if (permanentlyClosed) {\n setStatus('closed');\n return;\n }\n\n setStatus('closed');\n\n if (shouldReconnect && reconnectCount < maxReconnects) {\n // Exponential backoff: baseInterval * 2^reconnectCount\n const delay = baseInterval * Math.pow(2, reconnectCount);\n reconnectCount++;\n reconnectTimer = setTimeout(connect, delay);\n }\n };\n }\n\n // Initiate the first connection\n connect();\n\n return {\n data,\n status,\n\n send(value: TSend): void {\n if (socket && socket.readyState === WebSocket.OPEN) {\n socket.send(JSON.stringify(value));\n }\n },\n\n close(): void {\n permanentlyClosed = true;\n if (reconnectTimer !== null) {\n clearTimeout(reconnectTimer);\n reconnectTimer = null;\n }\n if (socket) {\n socket.close();\n socket = null;\n }\n setStatus('closed');\n },\n\n on(handler: (data: TReceive) => void): () => void {\n handlers.add(handler);\n return () => {\n handlers.delete(handler);\n };\n },\n };\n}\n"]}
package/dist/http.js CHANGED
@@ -1,5 +1,5 @@
1
- import { internalEffect } from './chunk-OUVOAYIO.js';
2
- import { createSignal } from './chunk-OZCHIVAZ.js';
1
+ import { internalEffect } from './chunk-TBWZZ3SI.js';
2
+ import { createSignal } from './chunk-HLM5BZZQ.js';
3
3
 
4
4
  // src/http/fetch.ts
5
5
  function createFetch(url, options) {
@@ -57,10 +57,10 @@ function createFetch(url, options) {
57
57
  if (typeof url === "function") {
58
58
  internalEffect(() => {
59
59
  url();
60
- execute();
60
+ void execute();
61
61
  });
62
62
  } else {
63
- execute();
63
+ void execute();
64
64
  }
65
65
  return {
66
66
  data,
package/dist/http.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/http/fetch.ts","../src/http/sse.ts","../src/http/ws.ts"],"names":[],"mappings":"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","file":"http.js","sourcesContent":["/**\n * Forma HTTP - Fetch\n *\n * Typed fetch wrapper with reactive signal integration.\n * Zero dependencies — native browser APIs only.\n */\n\nimport { createSignal, internalEffect } from 'forma/reactive';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface FetchOptions<T> extends Omit<RequestInit, 'signal'> {\n base?: string;\n params?: Record<string, string>;\n timeout?: number; // ms, default 30000\n transform?: (data: unknown) => T;\n}\n\nexport interface FetchResult<T> {\n data: () => T | null;\n error: () => Error | null;\n loading: () => boolean;\n refetch: () => Promise<void>;\n abort: () => void;\n}\n\n// ---------------------------------------------------------------------------\n// createFetch — reactive fetch with signals\n// ---------------------------------------------------------------------------\n\n/**\n * Create a reactive fetch that exposes data/error/loading as signals.\n *\n * If `url` is a signal getter (function), an effect auto-refetches when it\n * changes.\n *\n * ```ts\n * const { data, loading, error, refetch, abort } = createFetch<User[]>('/api/users');\n * ```\n */\nexport function createFetch<T>(\n url: string | (() => string),\n options?: FetchOptions<T>,\n): FetchResult<T> {\n const [data, setData] = createSignal<T | null>(null);\n const [error, setError] = createSignal<Error | null>(null);\n const [loading, setLoading] = createSignal<boolean>(false);\n\n let currentController: AbortController | null = null;\n\n /** Resolve the URL string, applying base and params. */\n function resolveURL(): string {\n const raw = typeof url === 'function' ? url() : url;\n const base = options?.base || (typeof window !== 'undefined' ? window.location.origin : '');\n const fullURL = new URL(raw, base || undefined);\n\n if (options?.params) {\n for (const [key, value] of Object.entries(options.params)) {\n fullURL.searchParams.set(key, value);\n }\n }\n\n return fullURL.toString();\n }\n\n /** Execute a single fetch request. */\n async function execute(): Promise<void> {\n // Abort any in-flight request\n if (currentController) {\n currentController.abort();\n }\n\n currentController = new AbortController();\n const controller = currentController;\n const timeoutMs = options?.timeout ?? 30_000;\n\n // Set up timeout\n const timeoutId = setTimeout(() => controller.abort(), timeoutMs);\n\n setLoading(true);\n setError(null);\n\n try {\n const resolvedURL = resolveURL();\n\n const { base: _base, params: _params, timeout: _timeout, transform, ...fetchInit } =\n options ?? {};\n\n const response = await fetch(resolvedURL, {\n ...fetchInit,\n signal: controller.signal,\n });\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n const json: unknown = await response.json();\n const transformed = transform ? transform(json) : (json as T);\n setData(transformed);\n } catch (err) {\n if (err instanceof Error && err.name === 'AbortError') {\n // Ignore aborts — they are intentional or timeouts\n return;\n }\n setError(err instanceof Error ? err : new Error(String(err)));\n } finally {\n clearTimeout(timeoutId);\n // Only update loading if this controller is still current\n if (currentController === controller) {\n currentController = null;\n setLoading(false);\n }\n }\n }\n\n // If url is a reactive getter, set up an effect to auto-refetch.\n if (typeof url === 'function') {\n internalEffect(() => {\n // Read the signal so the effect re-runs when it changes\n url();\n execute();\n });\n } else {\n // Kick off the first request immediately\n execute();\n }\n\n return {\n data,\n error,\n loading,\n refetch: execute,\n abort() {\n if (currentController) {\n currentController.abort();\n }\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// fetchJSON — simple one-shot helper\n// ---------------------------------------------------------------------------\n\n/**\n * One-shot fetch that returns parsed JSON.\n *\n * ```ts\n * const users = await fetchJSON<User[]>('/api/users');\n * ```\n */\nexport async function fetchJSON<T>(url: string, options?: RequestInit): Promise<T> {\n const response = await fetch(url, options);\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n return (await response.json()) as T;\n}\n","/**\n * Forma HTTP - Server-Sent Events\n *\n * Reactive SSE wrapper with signal integration.\n * Zero dependencies — native browser APIs only.\n */\n\nimport { createSignal } from 'forma/reactive';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface SSEOptions<T = unknown> {\n withCredentials?: boolean;\n headers?: Record<string, string>; // Note: native EventSource does not support custom headers\n /** Custom parser for incoming messages. Defaults to JSON.parse with raw data fallback. */\n parse?: (data: string) => T;\n}\n\nexport interface SSEConnection<T = unknown> {\n data: () => T | null;\n error: () => Event | null;\n connected: () => boolean;\n close: () => void;\n on(event: string, handler: (data: unknown) => void): () => void;\n}\n\n// ---------------------------------------------------------------------------\n// createSSE\n// ---------------------------------------------------------------------------\n\n/**\n * Create a reactive Server-Sent Events connection.\n *\n * ```ts\n * const sse = createSSE<{ message: string }>('/api/events');\n * createEffect(() => {\n * const msg = sse.data();\n * if (msg) console.log(msg.message);\n * });\n * ```\n */\nexport function createSSE<T = unknown>(\n url: string,\n options?: SSEOptions<T>,\n): SSEConnection<T> {\n const [data, setData] = createSignal<T | null>(null);\n const [error, setError] = createSignal<Event | null>(null);\n const [connected, setConnected] = createSignal<boolean>(false);\n\n const source = new EventSource(url, {\n withCredentials: options?.withCredentials ?? false,\n });\n\n source.onopen = () => {\n setConnected(true);\n setError(null);\n };\n\n const parseMessage = options?.parse ?? ((raw: string): T => {\n try { return JSON.parse(raw) as T; }\n catch { return raw as T; }\n });\n\n source.onmessage = (event: MessageEvent) => {\n setData(parseMessage(event.data as string));\n };\n\n source.onerror = (event: Event) => {\n setError(event);\n setConnected(false);\n };\n\n return {\n data,\n error,\n connected,\n\n close(): void {\n source.close();\n setConnected(false);\n },\n\n on(event: string, handler: (data: unknown) => void): () => void {\n const parseEvent = options?.parse ?? ((raw: string) => {\n try { return JSON.parse(raw); }\n catch { return raw; }\n });\n const listener = (e: MessageEvent) => {\n handler(parseEvent(e.data as string));\n };\n source.addEventListener(event, listener as EventListener);\n return () => {\n source.removeEventListener(event, listener as EventListener);\n };\n },\n };\n}\n","/**\n * Forma HTTP - WebSocket\n *\n * Reactive WebSocket wrapper with auto-reconnect and signal integration.\n * Zero dependencies — native browser APIs only.\n */\n\nimport { createSignal } from 'forma/reactive';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type WSStatus = 'connecting' | 'open' | 'closed' | 'error';\n\nexport interface WSOptions<TReceive = unknown> {\n protocols?: string | string[];\n reconnect?: boolean; // default true\n reconnectInterval?: number; // ms, default 1000\n maxReconnects?: number; // default 5\n /** Custom parser for incoming messages. Defaults to JSON.parse with raw data fallback. */\n parse?: (data: string) => TReceive;\n}\n\nexport interface WSConnection<TSend = unknown, TReceive = unknown> {\n data: () => TReceive | null;\n status: () => WSStatus;\n send(data: TSend): void;\n close(): void;\n on(handler: (data: TReceive) => void): () => void;\n}\n\n// ---------------------------------------------------------------------------\n// createWebSocket\n// ---------------------------------------------------------------------------\n\n/**\n * Create a reactive WebSocket connection with auto-reconnect.\n *\n * ```ts\n * const ws = createWebSocket<string, ChatMessage>('wss://chat.example.com');\n * ws.send('hello');\n * createEffect(() => {\n * const msg = ws.data();\n * if (msg) console.log(msg);\n * });\n * ```\n */\nexport function createWebSocket<TSend = unknown, TReceive = unknown>(\n url: string,\n options?: WSOptions<TReceive>,\n): WSConnection<TSend, TReceive> {\n const shouldReconnect = options?.reconnect ?? true;\n const baseInterval = options?.reconnectInterval ?? 1000;\n const maxReconnects = options?.maxReconnects ?? 5;\n\n const [data, setData] = createSignal<TReceive | null>(null);\n const [status, setStatus] = createSignal<WSStatus>('connecting');\n\n const handlers = new Set<(data: TReceive) => void>();\n\n let socket: WebSocket | null = null;\n let reconnectCount = 0;\n let reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n let permanentlyClosed = false;\n\n function connect(): void {\n if (permanentlyClosed) return;\n\n setStatus('connecting');\n socket = new WebSocket(url, options?.protocols);\n\n socket.onopen = () => {\n setStatus('open');\n reconnectCount = 0; // Reset on successful connection\n };\n\n const parseMessage = options?.parse ?? ((raw: string): TReceive => {\n try { return JSON.parse(raw) as TReceive; }\n catch { return raw as TReceive; }\n });\n\n socket.onmessage = (event: MessageEvent) => {\n const parsed = parseMessage(event.data as string);\n setData(parsed);\n for (const handler of handlers) {\n handler(parsed);\n }\n };\n\n socket.onerror = () => {\n setStatus('error');\n };\n\n socket.onclose = () => {\n if (permanentlyClosed) {\n setStatus('closed');\n return;\n }\n\n setStatus('closed');\n\n if (shouldReconnect && reconnectCount < maxReconnects) {\n // Exponential backoff: baseInterval * 2^reconnectCount\n const delay = baseInterval * Math.pow(2, reconnectCount);\n reconnectCount++;\n reconnectTimer = setTimeout(connect, delay);\n }\n };\n }\n\n // Initiate the first connection\n connect();\n\n return {\n data,\n status,\n\n send(value: TSend): void {\n if (socket && socket.readyState === WebSocket.OPEN) {\n socket.send(JSON.stringify(value));\n }\n },\n\n close(): void {\n permanentlyClosed = true;\n if (reconnectTimer !== null) {\n clearTimeout(reconnectTimer);\n reconnectTimer = null;\n }\n if (socket) {\n socket.close();\n socket = null;\n }\n setStatus('closed');\n },\n\n on(handler: (data: TReceive) => void): () => void {\n handlers.add(handler);\n return () => {\n handlers.delete(handler);\n };\n },\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/http/fetch.ts","../src/http/sse.ts","../src/http/ws.ts"],"names":[],"mappings":"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","file":"http.js","sourcesContent":["/**\n * Forma HTTP - Fetch\n *\n * Typed fetch wrapper with reactive signal integration.\n * Zero dependencies — native browser APIs only.\n */\n\nimport { createSignal, internalEffect } from 'forma/reactive';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface FetchOptions<T> extends Omit<RequestInit, 'signal'> {\n base?: string;\n params?: Record<string, string>;\n timeout?: number; // ms, default 30000\n transform?: (data: unknown) => T;\n}\n\nexport interface FetchResult<T> {\n data: () => T | null;\n error: () => Error | null;\n loading: () => boolean;\n refetch: () => Promise<void>;\n abort: () => void;\n}\n\n// ---------------------------------------------------------------------------\n// createFetch — reactive fetch with signals\n// ---------------------------------------------------------------------------\n\n/**\n * Create a reactive fetch that exposes data/error/loading as signals.\n *\n * If `url` is a signal getter (function), an effect auto-refetches when it\n * changes.\n *\n * ```ts\n * const { data, loading, error, refetch, abort } = createFetch<User[]>('/api/users');\n * ```\n */\nexport function createFetch<T>(\n url: string | (() => string),\n options?: FetchOptions<T>,\n): FetchResult<T> {\n const [data, setData] = createSignal<T | null>(null);\n const [error, setError] = createSignal<Error | null>(null);\n const [loading, setLoading] = createSignal<boolean>(false);\n\n let currentController: AbortController | null = null;\n\n /** Resolve the URL string, applying base and params. */\n function resolveURL(): string {\n const raw = typeof url === 'function' ? url() : url;\n const base = options?.base || (typeof window !== 'undefined' ? window.location.origin : '');\n const fullURL = new URL(raw, base || undefined);\n\n if (options?.params) {\n for (const [key, value] of Object.entries(options.params)) {\n fullURL.searchParams.set(key, value);\n }\n }\n\n return fullURL.toString();\n }\n\n /** Execute a single fetch request. */\n async function execute(): Promise<void> {\n // Abort any in-flight request\n if (currentController) {\n currentController.abort();\n }\n\n currentController = new AbortController();\n const controller = currentController;\n const timeoutMs = options?.timeout ?? 30_000;\n\n // Set up timeout\n const timeoutId = setTimeout(() => controller.abort(), timeoutMs);\n\n setLoading(true);\n setError(null);\n\n try {\n const resolvedURL = resolveURL();\n\n const { base: _base, params: _params, timeout: _timeout, transform, ...fetchInit } =\n options ?? {};\n\n const response = await fetch(resolvedURL, {\n ...fetchInit,\n signal: controller.signal,\n });\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n const json: unknown = await response.json();\n const transformed = transform ? transform(json) : (json as T);\n setData(transformed);\n } catch (err) {\n if (err instanceof Error && err.name === 'AbortError') {\n // Ignore aborts — they are intentional or timeouts\n return;\n }\n setError(err instanceof Error ? err : new Error(String(err)));\n } finally {\n clearTimeout(timeoutId);\n // Only update loading if this controller is still current\n if (currentController === controller) {\n currentController = null;\n setLoading(false);\n }\n }\n }\n\n // If url is a reactive getter, set up an effect to auto-refetch.\n if (typeof url === 'function') {\n internalEffect(() => {\n // Read the signal so the effect re-runs when it changes\n url();\n void execute();\n });\n } else {\n // Kick off the first request immediately\n void execute();\n }\n\n return {\n data,\n error,\n loading,\n refetch: execute,\n abort() {\n if (currentController) {\n currentController.abort();\n }\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// fetchJSON — simple one-shot helper\n// ---------------------------------------------------------------------------\n\n/**\n * One-shot fetch that returns parsed JSON.\n *\n * ```ts\n * const users = await fetchJSON<User[]>('/api/users');\n * ```\n */\nexport async function fetchJSON<T>(url: string, options?: RequestInit): Promise<T> {\n const response = await fetch(url, options);\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n return (await response.json()) as T;\n}\n","/**\n * Forma HTTP - Server-Sent Events\n *\n * Reactive SSE wrapper with signal integration.\n * Zero dependencies — native browser APIs only.\n */\n\nimport { createSignal } from 'forma/reactive';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface SSEOptions<T = unknown> {\n withCredentials?: boolean;\n headers?: Record<string, string>; // Note: native EventSource does not support custom headers\n /** Custom parser for incoming messages. Defaults to JSON.parse with raw data fallback. */\n parse?: (data: string) => T;\n}\n\nexport interface SSEConnection<T = unknown> {\n data: () => T | null;\n error: () => Event | null;\n connected: () => boolean;\n close: () => void;\n on(event: string, handler: (data: unknown) => void): () => void;\n}\n\n// ---------------------------------------------------------------------------\n// createSSE\n// ---------------------------------------------------------------------------\n\n/**\n * Create a reactive Server-Sent Events connection.\n *\n * ```ts\n * const sse = createSSE<{ message: string }>('/api/events');\n * createEffect(() => {\n * const msg = sse.data();\n * if (msg) console.log(msg.message);\n * });\n * ```\n */\nexport function createSSE<T = unknown>(\n url: string,\n options?: SSEOptions<T>,\n): SSEConnection<T> {\n const [data, setData] = createSignal<T | null>(null);\n const [error, setError] = createSignal<Event | null>(null);\n const [connected, setConnected] = createSignal<boolean>(false);\n\n const source = new EventSource(url, {\n withCredentials: options?.withCredentials ?? false,\n });\n\n source.onopen = () => {\n setConnected(true);\n setError(null);\n };\n\n const parseMessage = options?.parse ?? ((raw: string): T => {\n try { return JSON.parse(raw) as T; }\n catch { return raw as T; }\n });\n\n source.onmessage = (event: MessageEvent) => {\n setData(parseMessage(event.data as string));\n };\n\n source.onerror = (event: Event) => {\n setError(event);\n setConnected(false);\n };\n\n return {\n data,\n error,\n connected,\n\n close(): void {\n source.close();\n setConnected(false);\n },\n\n on(event: string, handler: (data: unknown) => void): () => void {\n const parseEvent = options?.parse ?? ((raw: string) => {\n try { return JSON.parse(raw); }\n catch { return raw; }\n });\n const listener = (e: MessageEvent) => {\n handler(parseEvent(e.data as string));\n };\n source.addEventListener(event, listener as EventListener);\n return () => {\n source.removeEventListener(event, listener as EventListener);\n };\n },\n };\n}\n","/**\n * Forma HTTP - WebSocket\n *\n * Reactive WebSocket wrapper with auto-reconnect and signal integration.\n * Zero dependencies — native browser APIs only.\n */\n\nimport { createSignal } from 'forma/reactive';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type WSStatus = 'connecting' | 'open' | 'closed' | 'error';\n\nexport interface WSOptions<TReceive = unknown> {\n protocols?: string | string[];\n reconnect?: boolean; // default true\n reconnectInterval?: number; // ms, default 1000\n maxReconnects?: number; // default 5\n /** Custom parser for incoming messages. Defaults to JSON.parse with raw data fallback. */\n parse?: (data: string) => TReceive;\n}\n\nexport interface WSConnection<TSend = unknown, TReceive = unknown> {\n data: () => TReceive | null;\n status: () => WSStatus;\n send(data: TSend): void;\n close(): void;\n on(handler: (data: TReceive) => void): () => void;\n}\n\n// ---------------------------------------------------------------------------\n// createWebSocket\n// ---------------------------------------------------------------------------\n\n/**\n * Create a reactive WebSocket connection with auto-reconnect.\n *\n * ```ts\n * const ws = createWebSocket<string, ChatMessage>('wss://chat.example.com');\n * ws.send('hello');\n * createEffect(() => {\n * const msg = ws.data();\n * if (msg) console.log(msg);\n * });\n * ```\n */\nexport function createWebSocket<TSend = unknown, TReceive = unknown>(\n url: string,\n options?: WSOptions<TReceive>,\n): WSConnection<TSend, TReceive> {\n const shouldReconnect = options?.reconnect ?? true;\n const baseInterval = options?.reconnectInterval ?? 1000;\n const maxReconnects = options?.maxReconnects ?? 5;\n\n const [data, setData] = createSignal<TReceive | null>(null);\n const [status, setStatus] = createSignal<WSStatus>('connecting');\n\n const handlers = new Set<(data: TReceive) => void>();\n\n let socket: WebSocket | null = null;\n let reconnectCount = 0;\n let reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n let permanentlyClosed = false;\n\n function connect(): void {\n if (permanentlyClosed) return;\n\n setStatus('connecting');\n socket = new WebSocket(url, options?.protocols);\n\n socket.onopen = () => {\n setStatus('open');\n reconnectCount = 0; // Reset on successful connection\n };\n\n const parseMessage = options?.parse ?? ((raw: string): TReceive => {\n try { return JSON.parse(raw) as TReceive; }\n catch { return raw as TReceive; }\n });\n\n socket.onmessage = (event: MessageEvent) => {\n const parsed = parseMessage(event.data as string);\n setData(parsed);\n for (const handler of handlers) {\n handler(parsed);\n }\n };\n\n socket.onerror = () => {\n setStatus('error');\n };\n\n socket.onclose = () => {\n if (permanentlyClosed) {\n setStatus('closed');\n return;\n }\n\n setStatus('closed');\n\n if (shouldReconnect && reconnectCount < maxReconnects) {\n // Exponential backoff: baseInterval * 2^reconnectCount\n const delay = baseInterval * Math.pow(2, reconnectCount);\n reconnectCount++;\n reconnectTimer = setTimeout(connect, delay);\n }\n };\n }\n\n // Initiate the first connection\n connect();\n\n return {\n data,\n status,\n\n send(value: TSend): void {\n if (socket && socket.readyState === WebSocket.OPEN) {\n socket.send(JSON.stringify(value));\n }\n },\n\n close(): void {\n permanentlyClosed = true;\n if (reconnectTimer !== null) {\n clearTimeout(reconnectTimer);\n reconnectTimer = null;\n }\n if (socket) {\n socket.close();\n socket = null;\n }\n setStatus('closed');\n },\n\n on(handler: (data: TReceive) => void): () => void {\n handlers.add(handler);\n return () => {\n handlers.delete(handler);\n };\n },\n };\n}\n"]}
package/dist/index.cjs CHANGED
@@ -1,14 +1,14 @@
1
1
  'use strict';
2
2
 
3
- var chunkV732ZBCU_cjs = require('./chunk-V732ZBCU.cjs');
4
- var chunkDCTOXHPF_cjs = require('./chunk-DCTOXHPF.cjs');
5
- var chunk3U57L2TY_cjs = require('./chunk-3U57L2TY.cjs');
3
+ var chunk7L3KHGEA_cjs = require('./chunk-7L3KHGEA.cjs');
4
+ var chunkBARF67I6_cjs = require('./chunk-BARF67I6.cjs');
5
+ var chunkQLPCVK7C_cjs = require('./chunk-QLPCVK7C.cjs');
6
6
 
7
7
  // src/dom/text.ts
8
8
  function createText(value) {
9
9
  if (typeof value === "function") {
10
10
  const node = new Text("");
11
- chunkDCTOXHPF_cjs.internalEffect(() => {
11
+ chunkBARF67I6_cjs.internalEffect(() => {
12
12
  node.data = value();
13
13
  });
14
14
  return node;
@@ -24,12 +24,12 @@ function mount(component, container) {
24
24
  }
25
25
  let disposeRoot;
26
26
  if (target.hasAttribute("data-forma-ssr")) {
27
- chunkDCTOXHPF_cjs.createRoot((dispose) => {
27
+ chunkBARF67I6_cjs.createRoot((dispose) => {
28
28
  disposeRoot = dispose;
29
- chunkV732ZBCU_cjs.hydrateIsland(component, target);
29
+ chunk7L3KHGEA_cjs.hydrateIsland(component, target);
30
30
  });
31
31
  } else {
32
- const dom = chunkDCTOXHPF_cjs.createRoot((dispose) => {
32
+ const dom = chunkBARF67I6_cjs.createRoot((dispose) => {
33
33
  disposeRoot = dispose;
34
34
  return component();
35
35
  });
@@ -55,7 +55,7 @@ function createSwitch(value, cases, fallback) {
55
55
  const cache2 = /* @__PURE__ */ new Map();
56
56
  let currentNode = null;
57
57
  let currentMatch = UNSET;
58
- const switchDispose = chunkDCTOXHPF_cjs.internalEffect(() => {
58
+ const switchDispose = chunkBARF67I6_cjs.internalEffect(() => {
59
59
  const val = value();
60
60
  if (val === currentMatch) return;
61
61
  const DEBUG = typeof globalThis.__FORMA_DEBUG__ !== "undefined";
@@ -90,9 +90,9 @@ function createSwitch(value, cases, fallback) {
90
90
  let entry = cache2.get(val);
91
91
  if (!entry) {
92
92
  let branchDispose;
93
- const node = chunkDCTOXHPF_cjs.createRoot((dispose) => {
93
+ const node = chunkBARF67I6_cjs.createRoot((dispose) => {
94
94
  branchDispose = dispose;
95
- return chunkDCTOXHPF_cjs.untrack(() => matchedCase.render());
95
+ return chunkBARF67I6_cjs.untrack(() => matchedCase.render());
96
96
  });
97
97
  entry = { node, dispose: branchDispose };
98
98
  cache2.set(val, entry);
@@ -135,7 +135,7 @@ function createPortal(children2, target) {
135
135
  }
136
136
  mountedNode = null;
137
137
  };
138
- chunkDCTOXHPF_cjs.createEffect(() => {
138
+ chunkBARF67I6_cjs.createEffect(() => {
139
139
  const node = children2();
140
140
  removeMountedNode();
141
141
  mountedNode = node;
@@ -154,9 +154,9 @@ function createErrorBoundary(tryFn, catchFn) {
154
154
  const fragment2 = document.createDocumentFragment();
155
155
  fragment2.appendChild(startMarker);
156
156
  fragment2.appendChild(endMarker);
157
- const [retryCount, setRetryCount] = chunk3U57L2TY_cjs.createSignal(0);
157
+ const [retryCount, setRetryCount] = chunkQLPCVK7C_cjs.createSignal(0);
158
158
  let currentNode = null;
159
- chunkDCTOXHPF_cjs.internalEffect(() => {
159
+ chunkBARF67I6_cjs.internalEffect(() => {
160
160
  retryCount();
161
161
  const parent2 = startMarker.parentNode;
162
162
  if (!parent2) return;
@@ -184,7 +184,7 @@ function createSuspense(fallback, children2) {
184
184
  const fragment2 = document.createDocumentFragment();
185
185
  fragment2.appendChild(startMarker);
186
186
  fragment2.appendChild(endMarker);
187
- const [pending, setPending] = chunk3U57L2TY_cjs.createSignal(0);
187
+ const [pending, setPending] = chunkQLPCVK7C_cjs.createSignal(0);
188
188
  let currentNode = null;
189
189
  let resolvedNode = null;
190
190
  let fallbackNode = null;
@@ -196,13 +196,13 @@ function createSuspense(fallback, children2) {
196
196
  setPending((p) => Math.max(0, p - 1));
197
197
  }
198
198
  };
199
- chunkDCTOXHPF_cjs.pushSuspenseContext(ctx);
199
+ chunkBARF67I6_cjs.pushSuspenseContext(ctx);
200
200
  try {
201
201
  resolvedNode = children2();
202
202
  } finally {
203
- chunkDCTOXHPF_cjs.popSuspenseContext();
203
+ chunkBARF67I6_cjs.popSuspenseContext();
204
204
  }
205
- chunkDCTOXHPF_cjs.internalEffect(() => {
205
+ chunkBARF67I6_cjs.internalEffect(() => {
206
206
  const parent2 = startMarker.parentNode;
207
207
  if (!parent2) return;
208
208
  const isPending = pending() > 0;
@@ -269,7 +269,7 @@ function activateIslands(registry) {
269
269
  const componentName = root.getAttribute("data-forma-component");
270
270
  const hydrateFn = registry[componentName];
271
271
  if (!hydrateFn) {
272
- if (chunkDCTOXHPF_cjs.__DEV__) console.warn(`[forma] No hydrate function for island "${componentName}" (id=${id})`);
272
+ if (chunkBARF67I6_cjs.__DEV__) console.warn(`[forma] No hydrate function for island "${componentName}" (id=${id})`);
273
273
  root.setAttribute("data-forma-status", "error");
274
274
  continue;
275
275
  }
@@ -325,13 +325,13 @@ function hydrateIslandRoot(root, id, componentName, hydrateFn, sharedProps) {
325
325
  const props = loadIslandProps(root, id, sharedProps);
326
326
  root.setAttribute("data-forma-status", "hydrating");
327
327
  let activeRoot = root;
328
- chunkDCTOXHPF_cjs.createRoot((dispose) => {
329
- activeRoot = chunkV732ZBCU_cjs.hydrateIsland(() => hydrateFn(root, props), root);
328
+ chunkBARF67I6_cjs.createRoot((dispose) => {
329
+ activeRoot = chunk7L3KHGEA_cjs.hydrateIsland(() => hydrateFn(root, props), root);
330
330
  activeRoot.__formaDispose = dispose;
331
331
  });
332
332
  activeRoot.setAttribute("data-forma-status", "active");
333
333
  } catch (err) {
334
- if (chunkDCTOXHPF_cjs.__DEV__) console.error(`[forma] Island "${componentName}" (id=${id}) failed:`, err);
334
+ if (chunkBARF67I6_cjs.__DEV__) console.error(`[forma] Island "${componentName}" (id=${id}) failed:`, err);
335
335
  root.setAttribute("data-forma-status", "error");
336
336
  }
337
337
  }
@@ -380,14 +380,14 @@ function defineComponent(setupOrDef) {
380
380
  try {
381
381
  cb();
382
382
  } catch (e) {
383
- chunkDCTOXHPF_cjs.reportError(e, "onUnmount");
383
+ chunkBARF67I6_cjs.reportError(e, "onUnmount");
384
384
  }
385
385
  }
386
386
  for (const d of ctx.disposers) {
387
387
  try {
388
388
  d();
389
389
  } catch (e) {
390
- chunkDCTOXHPF_cjs.reportError(e, "component disposer");
390
+ chunkBARF67I6_cjs.reportError(e, "component disposer");
391
391
  }
392
392
  }
393
393
  ctx.disposers.length = 0;
@@ -402,7 +402,7 @@ function defineComponent(setupOrDef) {
402
402
  ctx.unmountCallbacks.push(cleanup2);
403
403
  }
404
404
  } catch (e) {
405
- chunkDCTOXHPF_cjs.reportError(e, "onMount");
405
+ chunkBARF67I6_cjs.reportError(e, "onMount");
406
406
  }
407
407
  }
408
408
  return dom;
@@ -505,7 +505,7 @@ function createStore(initial) {
505
505
  function getSignal(path, initialValue) {
506
506
  let pair = signals.get(path);
507
507
  if (!pair) {
508
- pair = chunk3U57L2TY_cjs.createSignal(initialValue);
508
+ pair = chunkQLPCVK7C_cjs.createSignal(initialValue);
509
509
  signals.set(path, pair);
510
510
  registerChild(path);
511
511
  }
@@ -545,7 +545,7 @@ function createStore(initial) {
545
545
  if (isArr && ARRAY_MUTATORS.has(key)) {
546
546
  return (...args) => {
547
547
  let result;
548
- chunkDCTOXHPF_cjs.batch(() => {
548
+ chunkBARF67I6_cjs.batch(() => {
549
549
  const rawArgs = args.map(
550
550
  (a) => a != null && typeof a === "object" && a[RAW] ? a[RAW] : a
551
551
  );
@@ -659,11 +659,11 @@ function createStore(initial) {
659
659
  }
660
660
  const rootProxy = wrap(initial, "");
661
661
  function getCurrentSnapshot() {
662
- return chunkDCTOXHPF_cjs.untrack(() => deepClone(initial));
662
+ return chunkBARF67I6_cjs.untrack(() => deepClone(initial));
663
663
  }
664
664
  const setter = (partial) => {
665
665
  const updates = typeof partial === "function" ? partial(getCurrentSnapshot()) : partial;
666
- chunkDCTOXHPF_cjs.batch(() => {
666
+ chunkBARF67I6_cjs.batch(() => {
667
667
  for (const key of Object.keys(updates)) {
668
668
  rootProxy[key] = updates[key];
669
669
  }
@@ -678,11 +678,11 @@ function createHistory(source, options) {
678
678
  const maxLength = options?.maxLength ?? 100;
679
679
  let _stack = [sourceGet()];
680
680
  let _cursor = 0;
681
- const [stackSignal, setStackSignal] = chunk3U57L2TY_cjs.createSignal([..._stack]);
682
- const [cursorSignal, setCursorSignal] = chunk3U57L2TY_cjs.createSignal(_cursor);
683
- const [stackLenSignal, setStackLenSignal] = chunk3U57L2TY_cjs.createSignal(_stack.length);
681
+ const [stackSignal, setStackSignal] = chunkQLPCVK7C_cjs.createSignal([..._stack]);
682
+ const [cursorSignal, setCursorSignal] = chunkQLPCVK7C_cjs.createSignal(_cursor);
683
+ const [stackLenSignal, setStackLenSignal] = chunkQLPCVK7C_cjs.createSignal(_stack.length);
684
684
  function syncSignals() {
685
- chunkDCTOXHPF_cjs.batch(() => {
685
+ chunkBARF67I6_cjs.batch(() => {
686
686
  setStackSignal([..._stack]);
687
687
  setCursorSignal(_cursor);
688
688
  setStackLenSignal(_stack.length);
@@ -690,7 +690,7 @@ function createHistory(source, options) {
690
690
  }
691
691
  let ignoreNext = false;
692
692
  let isFirstRun = true;
693
- chunkDCTOXHPF_cjs.internalEffect(() => {
693
+ chunkBARF67I6_cjs.internalEffect(() => {
694
694
  const value = sourceGet();
695
695
  if (isFirstRun) {
696
696
  isFirstRun = false;
@@ -758,7 +758,7 @@ function persist(source, key, options) {
758
758
  }
759
759
  } catch {
760
760
  }
761
- chunkDCTOXHPF_cjs.internalEffect(() => {
761
+ chunkBARF67I6_cjs.internalEffect(() => {
762
762
  const value = sourceGet();
763
763
  try {
764
764
  const serialized = serialize(value);
@@ -1016,111 +1016,111 @@ function onMutation(el, handler, options) {
1016
1016
 
1017
1017
  Object.defineProperty(exports, "Fragment", {
1018
1018
  enumerable: true,
1019
- get: function () { return chunkV732ZBCU_cjs.Fragment; }
1019
+ get: function () { return chunk7L3KHGEA_cjs.Fragment; }
1020
1020
  });
1021
1021
  Object.defineProperty(exports, "cleanup", {
1022
1022
  enumerable: true,
1023
- get: function () { return chunkV732ZBCU_cjs.cleanup; }
1023
+ get: function () { return chunk7L3KHGEA_cjs.cleanup; }
1024
1024
  });
1025
1025
  Object.defineProperty(exports, "createList", {
1026
1026
  enumerable: true,
1027
- get: function () { return chunkV732ZBCU_cjs.createList; }
1027
+ get: function () { return chunk7L3KHGEA_cjs.createList; }
1028
1028
  });
1029
1029
  Object.defineProperty(exports, "createShow", {
1030
1030
  enumerable: true,
1031
- get: function () { return chunkV732ZBCU_cjs.createShow; }
1031
+ get: function () { return chunk7L3KHGEA_cjs.createShow; }
1032
1032
  });
1033
1033
  Object.defineProperty(exports, "fragment", {
1034
1034
  enumerable: true,
1035
- get: function () { return chunkV732ZBCU_cjs.fragment; }
1035
+ get: function () { return chunk7L3KHGEA_cjs.fragment; }
1036
1036
  });
1037
1037
  Object.defineProperty(exports, "h", {
1038
1038
  enumerable: true,
1039
- get: function () { return chunkV732ZBCU_cjs.h; }
1039
+ get: function () { return chunk7L3KHGEA_cjs.h; }
1040
1040
  });
1041
1041
  Object.defineProperty(exports, "hydrateIsland", {
1042
1042
  enumerable: true,
1043
- get: function () { return chunkV732ZBCU_cjs.hydrateIsland; }
1043
+ get: function () { return chunk7L3KHGEA_cjs.hydrateIsland; }
1044
1044
  });
1045
1045
  Object.defineProperty(exports, "reconcileList", {
1046
1046
  enumerable: true,
1047
- get: function () { return chunkV732ZBCU_cjs.reconcileList; }
1047
+ get: function () { return chunk7L3KHGEA_cjs.reconcileList; }
1048
1048
  });
1049
1049
  Object.defineProperty(exports, "batch", {
1050
1050
  enumerable: true,
1051
- get: function () { return chunkDCTOXHPF_cjs.batch; }
1051
+ get: function () { return chunkBARF67I6_cjs.batch; }
1052
1052
  });
1053
1053
  Object.defineProperty(exports, "createEffect", {
1054
1054
  enumerable: true,
1055
- get: function () { return chunkDCTOXHPF_cjs.createEffect; }
1055
+ get: function () { return chunkBARF67I6_cjs.createEffect; }
1056
1056
  });
1057
1057
  Object.defineProperty(exports, "createMemo", {
1058
1058
  enumerable: true,
1059
- get: function () { return chunkDCTOXHPF_cjs.createMemo; }
1059
+ get: function () { return chunkBARF67I6_cjs.createMemo; }
1060
1060
  });
1061
1061
  Object.defineProperty(exports, "createReducer", {
1062
1062
  enumerable: true,
1063
- get: function () { return chunkDCTOXHPF_cjs.createReducer; }
1063
+ get: function () { return chunkBARF67I6_cjs.createReducer; }
1064
1064
  });
1065
1065
  Object.defineProperty(exports, "createRef", {
1066
1066
  enumerable: true,
1067
- get: function () { return chunkDCTOXHPF_cjs.createRef; }
1067
+ get: function () { return chunkBARF67I6_cjs.createRef; }
1068
1068
  });
1069
1069
  Object.defineProperty(exports, "createResource", {
1070
1070
  enumerable: true,
1071
- get: function () { return chunkDCTOXHPF_cjs.createResource; }
1071
+ get: function () { return chunkBARF67I6_cjs.createResource; }
1072
1072
  });
1073
1073
  Object.defineProperty(exports, "createRoot", {
1074
1074
  enumerable: true,
1075
- get: function () { return chunkDCTOXHPF_cjs.createRoot; }
1075
+ get: function () { return chunkBARF67I6_cjs.createRoot; }
1076
1076
  });
1077
1077
  Object.defineProperty(exports, "getBatchDepth", {
1078
1078
  enumerable: true,
1079
- get: function () { return chunkDCTOXHPF_cjs.getBatchDepth; }
1079
+ get: function () { return chunkBARF67I6_cjs.getBatchDepth; }
1080
1080
  });
1081
1081
  Object.defineProperty(exports, "isComputed", {
1082
1082
  enumerable: true,
1083
- get: function () { return chunkDCTOXHPF_cjs.isComputed; }
1083
+ get: function () { return chunkBARF67I6_cjs.isComputed; }
1084
1084
  });
1085
1085
  Object.defineProperty(exports, "isEffect", {
1086
1086
  enumerable: true,
1087
- get: function () { return chunkDCTOXHPF_cjs.isEffect; }
1087
+ get: function () { return chunkBARF67I6_cjs.isEffect; }
1088
1088
  });
1089
1089
  Object.defineProperty(exports, "isEffectScope", {
1090
1090
  enumerable: true,
1091
- get: function () { return chunkDCTOXHPF_cjs.isEffectScope; }
1091
+ get: function () { return chunkBARF67I6_cjs.isEffectScope; }
1092
1092
  });
1093
1093
  Object.defineProperty(exports, "isSignal", {
1094
1094
  enumerable: true,
1095
- get: function () { return chunkDCTOXHPF_cjs.isSignal; }
1095
+ get: function () { return chunkBARF67I6_cjs.isSignal; }
1096
1096
  });
1097
1097
  Object.defineProperty(exports, "on", {
1098
1098
  enumerable: true,
1099
- get: function () { return chunkDCTOXHPF_cjs.on; }
1099
+ get: function () { return chunkBARF67I6_cjs.on; }
1100
1100
  });
1101
1101
  Object.defineProperty(exports, "onCleanup", {
1102
1102
  enumerable: true,
1103
- get: function () { return chunkDCTOXHPF_cjs.onCleanup; }
1103
+ get: function () { return chunkBARF67I6_cjs.onCleanup; }
1104
1104
  });
1105
1105
  Object.defineProperty(exports, "onError", {
1106
1106
  enumerable: true,
1107
- get: function () { return chunkDCTOXHPF_cjs.onError; }
1107
+ get: function () { return chunkBARF67I6_cjs.onError; }
1108
1108
  });
1109
1109
  Object.defineProperty(exports, "trigger", {
1110
1110
  enumerable: true,
1111
- get: function () { return chunkDCTOXHPF_cjs.trigger; }
1111
+ get: function () { return chunkBARF67I6_cjs.trigger; }
1112
1112
  });
1113
1113
  Object.defineProperty(exports, "untrack", {
1114
1114
  enumerable: true,
1115
- get: function () { return chunkDCTOXHPF_cjs.untrack; }
1115
+ get: function () { return chunkBARF67I6_cjs.untrack; }
1116
1116
  });
1117
1117
  Object.defineProperty(exports, "createComputed", {
1118
1118
  enumerable: true,
1119
- get: function () { return chunk3U57L2TY_cjs.createComputed; }
1119
+ get: function () { return chunkQLPCVK7C_cjs.createComputed; }
1120
1120
  });
1121
1121
  Object.defineProperty(exports, "createSignal", {
1122
1122
  enumerable: true,
1123
- get: function () { return chunk3U57L2TY_cjs.createSignal; }
1123
+ get: function () { return chunkQLPCVK7C_cjs.createSignal; }
1124
1124
  });
1125
1125
  exports.$ = $;
1126
1126
  exports.$$ = $$;