@getforma/core 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -5
- package/dist/{chunk-VKKPX4YU.js → chunk-5H52PKGF.js} +62 -12
- package/dist/chunk-5H52PKGF.js.map +1 -0
- package/dist/{chunk-VP5EOGM5.cjs → chunk-TSQ7AKFT.cjs} +62 -11
- package/dist/chunk-TSQ7AKFT.cjs.map +1 -0
- package/dist/forma-runtime-csp.js +2 -0
- package/dist/forma-runtime.js +2 -0
- package/dist/formajs-runtime-hardened.global.js +1 -1
- package/dist/formajs-runtime-hardened.global.js.map +1 -1
- package/dist/formajs-runtime.global.js +1 -1
- package/dist/formajs-runtime.global.js.map +1 -1
- package/dist/formajs.global.js +1 -1
- package/dist/formajs.global.js.map +1 -1
- package/dist/index.cjs +100 -69
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +43 -27
- package/dist/index.d.ts +43 -27
- package/dist/index.js +57 -27
- package/dist/index.js.map +1 -1
- package/dist/runtime-hardened.cjs +166 -50
- package/dist/runtime-hardened.cjs.map +1 -1
- package/dist/runtime-hardened.d.cts +86 -0
- package/dist/runtime-hardened.d.ts +86 -0
- package/dist/runtime-hardened.js +166 -50
- package/dist/runtime-hardened.js.map +1 -1
- package/dist/runtime.cjs +188 -72
- package/dist/runtime.cjs.map +1 -1
- package/dist/runtime.js +167 -51
- package/dist/runtime.js.map +1 -1
- package/dist/ssr/index.cjs +59 -71
- package/dist/ssr/index.cjs.map +1 -1
- package/dist/ssr/index.d.cts +4 -0
- package/dist/ssr/index.d.ts +4 -0
- package/dist/ssr/index.js +59 -71
- package/dist/ssr/index.js.map +1 -1
- package/package.json +24 -3
- package/dist/chunk-VKKPX4YU.js.map +0 -1
- package/dist/chunk-VP5EOGM5.cjs.map +0 -1
package/dist/index.d.cts
CHANGED
|
@@ -924,6 +924,8 @@ interface PersistOptions<T> {
|
|
|
924
924
|
serialize?: (v: T) => string;
|
|
925
925
|
/** Custom deserializer. Defaults to JSON.parse. */
|
|
926
926
|
deserialize?: (s: string) => T;
|
|
927
|
+
/** Optional validator — return true if the deserialized value is valid. Rejects corrupt/tampered data. */
|
|
928
|
+
validate?: (v: unknown) => v is T;
|
|
927
929
|
}
|
|
928
930
|
/**
|
|
929
931
|
* Persist a signal's value to storage.
|
|
@@ -940,14 +942,14 @@ interface PersistOptions<T> {
|
|
|
940
942
|
*/
|
|
941
943
|
declare function persist<T>(source: [get: () => T, set: (v: T) => void], key: string, options?: PersistOptions<T>): void;
|
|
942
944
|
|
|
943
|
-
interface EventBus<T extends Record<string,
|
|
945
|
+
interface EventBus<T extends Record<string, unknown>> {
|
|
944
946
|
on<K extends keyof T>(event: K, handler: (payload: T[K]) => void): () => void;
|
|
945
947
|
once<K extends keyof T>(event: K, handler: (payload: T[K]) => void): () => void;
|
|
946
948
|
emit<K extends keyof T>(event: K, payload: T[K]): void;
|
|
947
949
|
off<K extends keyof T>(event: K, handler: (payload: T[K]) => void): void;
|
|
948
950
|
clear(): void;
|
|
949
951
|
}
|
|
950
|
-
declare function createBus<T extends Record<string,
|
|
952
|
+
declare function createBus<T extends Record<string, unknown> = Record<string, unknown>>(): EventBus<T>;
|
|
951
953
|
|
|
952
954
|
declare function delegate<K extends keyof HTMLElementEventMap>(container: HTMLElement | Document, selector: string, event: K, handler: (e: HTMLElementEventMap[K], matchedEl: HTMLElement) => void, options?: AddEventListenerOptions): () => void;
|
|
953
955
|
|
|
@@ -967,7 +969,22 @@ declare function toggleClass(el: HTMLElement, className: string, force?: boolean
|
|
|
967
969
|
declare function setStyle(el: HTMLElement, styles: Partial<CSSStyleDeclaration>): void;
|
|
968
970
|
declare function setAttr(el: HTMLElement, attrs: Record<string, string | boolean | null>): void;
|
|
969
971
|
declare function setText(el: HTMLElement, text: string): void;
|
|
972
|
+
/**
|
|
973
|
+
* Set raw HTML on an element. **No sanitization is performed.**
|
|
974
|
+
*
|
|
975
|
+
* Prefer `setText()` for user-controlled content. Only use this when you
|
|
976
|
+
* trust the HTML source (e.g., server-rendered markup you control).
|
|
977
|
+
*
|
|
978
|
+
* @deprecated Use `setHTMLUnsafe` instead — renamed to signal risk.
|
|
979
|
+
*/
|
|
970
980
|
declare function setHTML(el: HTMLElement, html: string): void;
|
|
981
|
+
/**
|
|
982
|
+
* Set raw HTML on an element. **No sanitization is performed.**
|
|
983
|
+
*
|
|
984
|
+
* Prefer `setText()` for user-controlled content. Only use this when you
|
|
985
|
+
* trust the HTML source (e.g., server-rendered markup you control).
|
|
986
|
+
*/
|
|
987
|
+
declare function setHTMLUnsafe(el: HTMLElement, html: string): void;
|
|
971
988
|
|
|
972
989
|
declare function closest<T extends HTMLElement = HTMLElement>(el: HTMLElement, selector: string): T | null;
|
|
973
990
|
declare function children<T extends HTMLElement = HTMLElement>(el: HTMLElement, selector?: string): T[];
|
|
@@ -980,22 +997,26 @@ declare function onResize(el: HTMLElement, handler: (entry: ResizeObserverEntry)
|
|
|
980
997
|
declare function onIntersect(el: HTMLElement, handler: (entry: IntersectionObserverEntry) => void, options?: IntersectionObserverInit): () => void;
|
|
981
998
|
declare function onMutation(el: HTMLElement, handler: (mutations: MutationRecord[]) => void, options?: MutationObserverInit): () => void;
|
|
982
999
|
|
|
983
|
-
|
|
984
|
-
* Forma Storage - Local
|
|
985
|
-
*
|
|
986
|
-
* Typed localStorage wrapper with graceful error handling.
|
|
987
|
-
* Zero dependencies — native browser APIs only.
|
|
988
|
-
*/
|
|
989
|
-
interface TypedStorage$1<T> {
|
|
1000
|
+
interface TypedStorage<T> {
|
|
990
1001
|
get(): T | null;
|
|
991
1002
|
set(value: T): void;
|
|
992
1003
|
remove(): void;
|
|
993
1004
|
key: string;
|
|
994
1005
|
}
|
|
995
|
-
interface StorageOptions
|
|
1006
|
+
interface StorageOptions<T> {
|
|
996
1007
|
serialize?: (v: T) => string;
|
|
997
1008
|
deserialize?: (s: string) => T;
|
|
1009
|
+
/** Optional validator — return true if the deserialized value is valid. */
|
|
1010
|
+
validate?: (v: unknown) => v is T;
|
|
998
1011
|
}
|
|
1012
|
+
|
|
1013
|
+
/**
|
|
1014
|
+
* Forma Storage - Local
|
|
1015
|
+
*
|
|
1016
|
+
* Typed localStorage wrapper with graceful error handling.
|
|
1017
|
+
* Zero dependencies — native browser APIs only.
|
|
1018
|
+
*/
|
|
1019
|
+
|
|
999
1020
|
/**
|
|
1000
1021
|
* Create a typed localStorage wrapper for the given key.
|
|
1001
1022
|
*
|
|
@@ -1006,7 +1027,7 @@ interface StorageOptions$1<T> {
|
|
|
1006
1027
|
* store.remove();
|
|
1007
1028
|
* ```
|
|
1008
1029
|
*/
|
|
1009
|
-
declare function createLocalStorage<T>(key: string, options?: StorageOptions
|
|
1030
|
+
declare function createLocalStorage<T>(key: string, options?: StorageOptions<T>): TypedStorage<T>;
|
|
1010
1031
|
|
|
1011
1032
|
/**
|
|
1012
1033
|
* Forma Storage - Session
|
|
@@ -1014,16 +1035,7 @@ declare function createLocalStorage<T>(key: string, options?: StorageOptions$1<T
|
|
|
1014
1035
|
* Typed sessionStorage wrapper with graceful error handling.
|
|
1015
1036
|
* Zero dependencies — native browser APIs only.
|
|
1016
1037
|
*/
|
|
1017
|
-
|
|
1018
|
-
get(): T | null;
|
|
1019
|
-
set(value: T): void;
|
|
1020
|
-
remove(): void;
|
|
1021
|
-
key: string;
|
|
1022
|
-
}
|
|
1023
|
-
interface StorageOptions<T> {
|
|
1024
|
-
serialize?: (v: T) => string;
|
|
1025
|
-
deserialize?: (s: string) => T;
|
|
1026
|
-
}
|
|
1038
|
+
|
|
1027
1039
|
/**
|
|
1028
1040
|
* Create a typed sessionStorage wrapper for the given key.
|
|
1029
1041
|
*
|
|
@@ -1106,9 +1118,11 @@ declare function fetchJSON<T>(url: string, options?: RequestInit): Promise<T>;
|
|
|
1106
1118
|
* Reactive SSE wrapper with signal integration.
|
|
1107
1119
|
* Zero dependencies — native browser APIs only.
|
|
1108
1120
|
*/
|
|
1109
|
-
interface SSEOptions {
|
|
1121
|
+
interface SSEOptions<T = unknown> {
|
|
1110
1122
|
withCredentials?: boolean;
|
|
1111
1123
|
headers?: Record<string, string>;
|
|
1124
|
+
/** Custom parser for incoming messages. Defaults to JSON.parse with raw data fallback. */
|
|
1125
|
+
parse?: (data: string) => T;
|
|
1112
1126
|
}
|
|
1113
1127
|
interface SSEConnection<T = unknown> {
|
|
1114
1128
|
data: () => T | null;
|
|
@@ -1128,7 +1142,7 @@ interface SSEConnection<T = unknown> {
|
|
|
1128
1142
|
* });
|
|
1129
1143
|
* ```
|
|
1130
1144
|
*/
|
|
1131
|
-
declare function createSSE<T = unknown>(url: string, options?: SSEOptions): SSEConnection<T>;
|
|
1145
|
+
declare function createSSE<T = unknown>(url: string, options?: SSEOptions<T>): SSEConnection<T>;
|
|
1132
1146
|
|
|
1133
1147
|
/**
|
|
1134
1148
|
* Forma HTTP - WebSocket
|
|
@@ -1137,11 +1151,13 @@ declare function createSSE<T = unknown>(url: string, options?: SSEOptions): SSEC
|
|
|
1137
1151
|
* Zero dependencies — native browser APIs only.
|
|
1138
1152
|
*/
|
|
1139
1153
|
type WSStatus = 'connecting' | 'open' | 'closed' | 'error';
|
|
1140
|
-
interface WSOptions {
|
|
1154
|
+
interface WSOptions<TReceive = unknown> {
|
|
1141
1155
|
protocols?: string | string[];
|
|
1142
1156
|
reconnect?: boolean;
|
|
1143
1157
|
reconnectInterval?: number;
|
|
1144
1158
|
maxReconnects?: number;
|
|
1159
|
+
/** Custom parser for incoming messages. Defaults to JSON.parse with raw data fallback. */
|
|
1160
|
+
parse?: (data: string) => TReceive;
|
|
1145
1161
|
}
|
|
1146
1162
|
interface WSConnection<TSend = unknown, TReceive = unknown> {
|
|
1147
1163
|
data: () => TReceive | null;
|
|
@@ -1162,7 +1178,7 @@ interface WSConnection<TSend = unknown, TReceive = unknown> {
|
|
|
1162
1178
|
* });
|
|
1163
1179
|
* ```
|
|
1164
1180
|
*/
|
|
1165
|
-
declare function createWebSocket<TSend = unknown, TReceive = unknown>(url: string, options?: WSOptions): WSConnection<TSend, TReceive>;
|
|
1181
|
+
declare function createWebSocket<TSend = unknown, TReceive = unknown>(url: string, options?: WSOptions<TReceive>): WSConnection<TSend, TReceive>;
|
|
1166
1182
|
|
|
1167
1183
|
/**
|
|
1168
1184
|
* FormaJS Server - Action
|
|
@@ -1327,7 +1343,7 @@ declare function withRevalidation<T>(data: T, revalidate: Record<string, unknown
|
|
|
1327
1343
|
* @param endpoint - The RPC endpoint path (e.g. "/rpc/createTodo_a1b2c3")
|
|
1328
1344
|
* @returns An async function that sends args to the server and returns the result
|
|
1329
1345
|
*/
|
|
1330
|
-
declare function $$serverFunction<T extends (...args:
|
|
1346
|
+
declare function $$serverFunction<T extends (...args: unknown[]) => Promise<unknown>>(endpoint: string): T;
|
|
1331
1347
|
|
|
1332
1348
|
/**
|
|
1333
1349
|
* FormaJS Server - RPC Handler
|
|
@@ -1391,4 +1407,4 @@ declare function renderLocal(slotsJson: string): Promise<string>;
|
|
|
1391
1407
|
/** Fragment render (single island) via WASM. */
|
|
1392
1408
|
declare function renderIsland(slotsJson: string, islandId: number): Promise<string>;
|
|
1393
1409
|
|
|
1394
|
-
export { $, $$, $$serverFunction, type Action, type ActionOptions, Fragment, type IslandHydrateFn, type MutationResponse, type RPCRequest, type RPCResponse, activateIslands, addClass, applyRevalidation, batch, children, cleanup, closest, createAction, createBus, createComputed, createContext, createEffect, createErrorBoundary, createFetch, createHistory, createIndexedDB, createList, createLocalStorage, createMemo, createPortal, createRPCMiddleware, createReducer, createRef, createResource, createRoot, createSSE, createSessionStorage, createShow, createStore, createSuspense, createSwitch, createText, createWebSocket, defineComponent, delegate, disposeComponent, enableAutoRevalidation, fetchJSON, fragment, getRegisteredEndpoints, getServerFunction, h, handleRPC, hydrateIsland, inject, longestIncreasingSubsequence, mount, nextSibling, on, onCleanup, onError, onIntersect, onKey, onMount, onMutation, onResize, onUnmount, parent, persist, prevSibling, provide, reconcileList, registerResource, registerServerFunction, removeClass, renderIsland, renderLocal, setAttr, setHTML, setStyle, setText, siblings, toggleClass, trackDisposer, unprovide, unregisterResource, untrack, withRevalidation };
|
|
1410
|
+
export { $, $$, $$serverFunction, type Action, type ActionOptions, Fragment, type IslandHydrateFn, type MutationResponse, type RPCRequest, type RPCResponse, activateIslands, addClass, applyRevalidation, batch, children, cleanup, closest, createAction, createBus, createComputed, createContext, createEffect, createErrorBoundary, createFetch, createHistory, createIndexedDB, createList, createLocalStorage, createMemo, createPortal, createRPCMiddleware, createReducer, createRef, createResource, createRoot, createSSE, createSessionStorage, createShow, createStore, createSuspense, createSwitch, createText, createWebSocket, defineComponent, delegate, disposeComponent, enableAutoRevalidation, fetchJSON, fragment, getRegisteredEndpoints, getServerFunction, h, handleRPC, hydrateIsland, inject, longestIncreasingSubsequence, mount, nextSibling, on, onCleanup, onError, onIntersect, onKey, onMount, onMutation, onResize, onUnmount, parent, persist, prevSibling, provide, reconcileList, registerResource, registerServerFunction, removeClass, renderIsland, renderLocal, setAttr, setHTML, setHTMLUnsafe, setStyle, setText, siblings, toggleClass, trackDisposer, unprovide, unregisterResource, untrack, withRevalidation };
|
package/dist/index.d.ts
CHANGED
|
@@ -924,6 +924,8 @@ interface PersistOptions<T> {
|
|
|
924
924
|
serialize?: (v: T) => string;
|
|
925
925
|
/** Custom deserializer. Defaults to JSON.parse. */
|
|
926
926
|
deserialize?: (s: string) => T;
|
|
927
|
+
/** Optional validator — return true if the deserialized value is valid. Rejects corrupt/tampered data. */
|
|
928
|
+
validate?: (v: unknown) => v is T;
|
|
927
929
|
}
|
|
928
930
|
/**
|
|
929
931
|
* Persist a signal's value to storage.
|
|
@@ -940,14 +942,14 @@ interface PersistOptions<T> {
|
|
|
940
942
|
*/
|
|
941
943
|
declare function persist<T>(source: [get: () => T, set: (v: T) => void], key: string, options?: PersistOptions<T>): void;
|
|
942
944
|
|
|
943
|
-
interface EventBus<T extends Record<string,
|
|
945
|
+
interface EventBus<T extends Record<string, unknown>> {
|
|
944
946
|
on<K extends keyof T>(event: K, handler: (payload: T[K]) => void): () => void;
|
|
945
947
|
once<K extends keyof T>(event: K, handler: (payload: T[K]) => void): () => void;
|
|
946
948
|
emit<K extends keyof T>(event: K, payload: T[K]): void;
|
|
947
949
|
off<K extends keyof T>(event: K, handler: (payload: T[K]) => void): void;
|
|
948
950
|
clear(): void;
|
|
949
951
|
}
|
|
950
|
-
declare function createBus<T extends Record<string,
|
|
952
|
+
declare function createBus<T extends Record<string, unknown> = Record<string, unknown>>(): EventBus<T>;
|
|
951
953
|
|
|
952
954
|
declare function delegate<K extends keyof HTMLElementEventMap>(container: HTMLElement | Document, selector: string, event: K, handler: (e: HTMLElementEventMap[K], matchedEl: HTMLElement) => void, options?: AddEventListenerOptions): () => void;
|
|
953
955
|
|
|
@@ -967,7 +969,22 @@ declare function toggleClass(el: HTMLElement, className: string, force?: boolean
|
|
|
967
969
|
declare function setStyle(el: HTMLElement, styles: Partial<CSSStyleDeclaration>): void;
|
|
968
970
|
declare function setAttr(el: HTMLElement, attrs: Record<string, string | boolean | null>): void;
|
|
969
971
|
declare function setText(el: HTMLElement, text: string): void;
|
|
972
|
+
/**
|
|
973
|
+
* Set raw HTML on an element. **No sanitization is performed.**
|
|
974
|
+
*
|
|
975
|
+
* Prefer `setText()` for user-controlled content. Only use this when you
|
|
976
|
+
* trust the HTML source (e.g., server-rendered markup you control).
|
|
977
|
+
*
|
|
978
|
+
* @deprecated Use `setHTMLUnsafe` instead — renamed to signal risk.
|
|
979
|
+
*/
|
|
970
980
|
declare function setHTML(el: HTMLElement, html: string): void;
|
|
981
|
+
/**
|
|
982
|
+
* Set raw HTML on an element. **No sanitization is performed.**
|
|
983
|
+
*
|
|
984
|
+
* Prefer `setText()` for user-controlled content. Only use this when you
|
|
985
|
+
* trust the HTML source (e.g., server-rendered markup you control).
|
|
986
|
+
*/
|
|
987
|
+
declare function setHTMLUnsafe(el: HTMLElement, html: string): void;
|
|
971
988
|
|
|
972
989
|
declare function closest<T extends HTMLElement = HTMLElement>(el: HTMLElement, selector: string): T | null;
|
|
973
990
|
declare function children<T extends HTMLElement = HTMLElement>(el: HTMLElement, selector?: string): T[];
|
|
@@ -980,22 +997,26 @@ declare function onResize(el: HTMLElement, handler: (entry: ResizeObserverEntry)
|
|
|
980
997
|
declare function onIntersect(el: HTMLElement, handler: (entry: IntersectionObserverEntry) => void, options?: IntersectionObserverInit): () => void;
|
|
981
998
|
declare function onMutation(el: HTMLElement, handler: (mutations: MutationRecord[]) => void, options?: MutationObserverInit): () => void;
|
|
982
999
|
|
|
983
|
-
|
|
984
|
-
* Forma Storage - Local
|
|
985
|
-
*
|
|
986
|
-
* Typed localStorage wrapper with graceful error handling.
|
|
987
|
-
* Zero dependencies — native browser APIs only.
|
|
988
|
-
*/
|
|
989
|
-
interface TypedStorage$1<T> {
|
|
1000
|
+
interface TypedStorage<T> {
|
|
990
1001
|
get(): T | null;
|
|
991
1002
|
set(value: T): void;
|
|
992
1003
|
remove(): void;
|
|
993
1004
|
key: string;
|
|
994
1005
|
}
|
|
995
|
-
interface StorageOptions
|
|
1006
|
+
interface StorageOptions<T> {
|
|
996
1007
|
serialize?: (v: T) => string;
|
|
997
1008
|
deserialize?: (s: string) => T;
|
|
1009
|
+
/** Optional validator — return true if the deserialized value is valid. */
|
|
1010
|
+
validate?: (v: unknown) => v is T;
|
|
998
1011
|
}
|
|
1012
|
+
|
|
1013
|
+
/**
|
|
1014
|
+
* Forma Storage - Local
|
|
1015
|
+
*
|
|
1016
|
+
* Typed localStorage wrapper with graceful error handling.
|
|
1017
|
+
* Zero dependencies — native browser APIs only.
|
|
1018
|
+
*/
|
|
1019
|
+
|
|
999
1020
|
/**
|
|
1000
1021
|
* Create a typed localStorage wrapper for the given key.
|
|
1001
1022
|
*
|
|
@@ -1006,7 +1027,7 @@ interface StorageOptions$1<T> {
|
|
|
1006
1027
|
* store.remove();
|
|
1007
1028
|
* ```
|
|
1008
1029
|
*/
|
|
1009
|
-
declare function createLocalStorage<T>(key: string, options?: StorageOptions
|
|
1030
|
+
declare function createLocalStorage<T>(key: string, options?: StorageOptions<T>): TypedStorage<T>;
|
|
1010
1031
|
|
|
1011
1032
|
/**
|
|
1012
1033
|
* Forma Storage - Session
|
|
@@ -1014,16 +1035,7 @@ declare function createLocalStorage<T>(key: string, options?: StorageOptions$1<T
|
|
|
1014
1035
|
* Typed sessionStorage wrapper with graceful error handling.
|
|
1015
1036
|
* Zero dependencies — native browser APIs only.
|
|
1016
1037
|
*/
|
|
1017
|
-
|
|
1018
|
-
get(): T | null;
|
|
1019
|
-
set(value: T): void;
|
|
1020
|
-
remove(): void;
|
|
1021
|
-
key: string;
|
|
1022
|
-
}
|
|
1023
|
-
interface StorageOptions<T> {
|
|
1024
|
-
serialize?: (v: T) => string;
|
|
1025
|
-
deserialize?: (s: string) => T;
|
|
1026
|
-
}
|
|
1038
|
+
|
|
1027
1039
|
/**
|
|
1028
1040
|
* Create a typed sessionStorage wrapper for the given key.
|
|
1029
1041
|
*
|
|
@@ -1106,9 +1118,11 @@ declare function fetchJSON<T>(url: string, options?: RequestInit): Promise<T>;
|
|
|
1106
1118
|
* Reactive SSE wrapper with signal integration.
|
|
1107
1119
|
* Zero dependencies — native browser APIs only.
|
|
1108
1120
|
*/
|
|
1109
|
-
interface SSEOptions {
|
|
1121
|
+
interface SSEOptions<T = unknown> {
|
|
1110
1122
|
withCredentials?: boolean;
|
|
1111
1123
|
headers?: Record<string, string>;
|
|
1124
|
+
/** Custom parser for incoming messages. Defaults to JSON.parse with raw data fallback. */
|
|
1125
|
+
parse?: (data: string) => T;
|
|
1112
1126
|
}
|
|
1113
1127
|
interface SSEConnection<T = unknown> {
|
|
1114
1128
|
data: () => T | null;
|
|
@@ -1128,7 +1142,7 @@ interface SSEConnection<T = unknown> {
|
|
|
1128
1142
|
* });
|
|
1129
1143
|
* ```
|
|
1130
1144
|
*/
|
|
1131
|
-
declare function createSSE<T = unknown>(url: string, options?: SSEOptions): SSEConnection<T>;
|
|
1145
|
+
declare function createSSE<T = unknown>(url: string, options?: SSEOptions<T>): SSEConnection<T>;
|
|
1132
1146
|
|
|
1133
1147
|
/**
|
|
1134
1148
|
* Forma HTTP - WebSocket
|
|
@@ -1137,11 +1151,13 @@ declare function createSSE<T = unknown>(url: string, options?: SSEOptions): SSEC
|
|
|
1137
1151
|
* Zero dependencies — native browser APIs only.
|
|
1138
1152
|
*/
|
|
1139
1153
|
type WSStatus = 'connecting' | 'open' | 'closed' | 'error';
|
|
1140
|
-
interface WSOptions {
|
|
1154
|
+
interface WSOptions<TReceive = unknown> {
|
|
1141
1155
|
protocols?: string | string[];
|
|
1142
1156
|
reconnect?: boolean;
|
|
1143
1157
|
reconnectInterval?: number;
|
|
1144
1158
|
maxReconnects?: number;
|
|
1159
|
+
/** Custom parser for incoming messages. Defaults to JSON.parse with raw data fallback. */
|
|
1160
|
+
parse?: (data: string) => TReceive;
|
|
1145
1161
|
}
|
|
1146
1162
|
interface WSConnection<TSend = unknown, TReceive = unknown> {
|
|
1147
1163
|
data: () => TReceive | null;
|
|
@@ -1162,7 +1178,7 @@ interface WSConnection<TSend = unknown, TReceive = unknown> {
|
|
|
1162
1178
|
* });
|
|
1163
1179
|
* ```
|
|
1164
1180
|
*/
|
|
1165
|
-
declare function createWebSocket<TSend = unknown, TReceive = unknown>(url: string, options?: WSOptions): WSConnection<TSend, TReceive>;
|
|
1181
|
+
declare function createWebSocket<TSend = unknown, TReceive = unknown>(url: string, options?: WSOptions<TReceive>): WSConnection<TSend, TReceive>;
|
|
1166
1182
|
|
|
1167
1183
|
/**
|
|
1168
1184
|
* FormaJS Server - Action
|
|
@@ -1327,7 +1343,7 @@ declare function withRevalidation<T>(data: T, revalidate: Record<string, unknown
|
|
|
1327
1343
|
* @param endpoint - The RPC endpoint path (e.g. "/rpc/createTodo_a1b2c3")
|
|
1328
1344
|
* @returns An async function that sends args to the server and returns the result
|
|
1329
1345
|
*/
|
|
1330
|
-
declare function $$serverFunction<T extends (...args:
|
|
1346
|
+
declare function $$serverFunction<T extends (...args: unknown[]) => Promise<unknown>>(endpoint: string): T;
|
|
1331
1347
|
|
|
1332
1348
|
/**
|
|
1333
1349
|
* FormaJS Server - RPC Handler
|
|
@@ -1391,4 +1407,4 @@ declare function renderLocal(slotsJson: string): Promise<string>;
|
|
|
1391
1407
|
/** Fragment render (single island) via WASM. */
|
|
1392
1408
|
declare function renderIsland(slotsJson: string, islandId: number): Promise<string>;
|
|
1393
1409
|
|
|
1394
|
-
export { $, $$, $$serverFunction, type Action, type ActionOptions, Fragment, type IslandHydrateFn, type MutationResponse, type RPCRequest, type RPCResponse, activateIslands, addClass, applyRevalidation, batch, children, cleanup, closest, createAction, createBus, createComputed, createContext, createEffect, createErrorBoundary, createFetch, createHistory, createIndexedDB, createList, createLocalStorage, createMemo, createPortal, createRPCMiddleware, createReducer, createRef, createResource, createRoot, createSSE, createSessionStorage, createShow, createStore, createSuspense, createSwitch, createText, createWebSocket, defineComponent, delegate, disposeComponent, enableAutoRevalidation, fetchJSON, fragment, getRegisteredEndpoints, getServerFunction, h, handleRPC, hydrateIsland, inject, longestIncreasingSubsequence, mount, nextSibling, on, onCleanup, onError, onIntersect, onKey, onMount, onMutation, onResize, onUnmount, parent, persist, prevSibling, provide, reconcileList, registerResource, registerServerFunction, removeClass, renderIsland, renderLocal, setAttr, setHTML, setStyle, setText, siblings, toggleClass, trackDisposer, unprovide, unregisterResource, untrack, withRevalidation };
|
|
1410
|
+
export { $, $$, $$serverFunction, type Action, type ActionOptions, Fragment, type IslandHydrateFn, type MutationResponse, type RPCRequest, type RPCResponse, activateIslands, addClass, applyRevalidation, batch, children, cleanup, closest, createAction, createBus, createComputed, createContext, createEffect, createErrorBoundary, createFetch, createHistory, createIndexedDB, createList, createLocalStorage, createMemo, createPortal, createRPCMiddleware, createReducer, createRef, createResource, createRoot, createSSE, createSessionStorage, createShow, createStore, createSuspense, createSwitch, createText, createWebSocket, defineComponent, delegate, disposeComponent, enableAutoRevalidation, fetchJSON, fragment, getRegisteredEndpoints, getServerFunction, h, handleRPC, hydrateIsland, inject, longestIncreasingSubsequence, mount, nextSibling, on, onCleanup, onError, onIntersect, onKey, onMount, onMutation, onResize, onUnmount, parent, persist, prevSibling, provide, reconcileList, registerResource, registerServerFunction, removeClass, renderIsland, renderLocal, setAttr, setHTML, setHTMLUnsafe, setStyle, setText, siblings, toggleClass, trackDisposer, unprovide, unregisterResource, untrack, withRevalidation };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { internalEffect, createRoot, hydrateIsland, untrack, createEffect, pushSuspenseContext, popSuspenseContext, batch } from './chunk-
|
|
2
|
-
export { Fragment, batch, cleanup, createEffect, createList, createMemo, createReducer, createRef, createResource, createRoot, createShow, fragment, h, hydrateIsland, longestIncreasingSubsequence, on, onCleanup, onError, reconcileList, untrack } from './chunk-
|
|
1
|
+
import { internalEffect, createRoot, hydrateIsland, untrack, createEffect, pushSuspenseContext, popSuspenseContext, __DEV__, batch } from './chunk-5H52PKGF.js';
|
|
2
|
+
export { Fragment, batch, cleanup, createEffect, createList, createMemo, createReducer, createRef, createResource, createRoot, createShow, fragment, h, hydrateIsland, longestIncreasingSubsequence, on, onCleanup, onError, reconcileList, untrack } from './chunk-5H52PKGF.js';
|
|
3
3
|
import { createSignal, createValueSignal } from './chunk-KX5WRZH7.js';
|
|
4
4
|
export { createComputed, createSignal } from './chunk-KX5WRZH7.js';
|
|
5
5
|
|
|
@@ -238,13 +238,13 @@ function activateIslands(registry2) {
|
|
|
238
238
|
const componentName = root.getAttribute("data-forma-component");
|
|
239
239
|
const hydrateFn = registry2[componentName];
|
|
240
240
|
if (!hydrateFn) {
|
|
241
|
-
console.warn(`[forma] No hydrate function for island "${componentName}" (id=${id})`);
|
|
241
|
+
if (__DEV__) console.warn(`[forma] No hydrate function for island "${componentName}" (id=${id})`);
|
|
242
242
|
root.setAttribute("data-forma-status", "error");
|
|
243
243
|
continue;
|
|
244
244
|
}
|
|
245
245
|
const trigger = root.getAttribute("data-forma-hydrate") || "load";
|
|
246
246
|
if (trigger === "interaction" || trigger === "idle") {
|
|
247
|
-
console.warn(`[forma] Trigger "${trigger}" not yet implemented for island "${componentName}" (id=${id}), falling back to load`);
|
|
247
|
+
if (__DEV__) console.warn(`[forma] Trigger "${trigger}" not yet implemented for island "${componentName}" (id=${id}), falling back to load`);
|
|
248
248
|
}
|
|
249
249
|
if (trigger === "visible") {
|
|
250
250
|
const observer = new IntersectionObserver(
|
|
@@ -274,7 +274,7 @@ function hydrateIslandRoot(root, id, componentName, hydrateFn, sharedProps) {
|
|
|
274
274
|
});
|
|
275
275
|
activeRoot.setAttribute("data-forma-status", "active");
|
|
276
276
|
} catch (err) {
|
|
277
|
-
console.error(`[forma] Island "${componentName}" (id=${id}) failed:`, err);
|
|
277
|
+
if (__DEV__) console.error(`[forma] Island "${componentName}" (id=${id}) failed:`, err);
|
|
278
278
|
root.setAttribute("data-forma-status", "error");
|
|
279
279
|
}
|
|
280
280
|
}
|
|
@@ -685,11 +685,14 @@ function persist(source, key, options) {
|
|
|
685
685
|
const storage = options?.storage ?? globalThis.localStorage;
|
|
686
686
|
const serialize = options?.serialize ?? JSON.stringify;
|
|
687
687
|
const deserialize = options?.deserialize ?? JSON.parse;
|
|
688
|
+
const validate = options?.validate;
|
|
688
689
|
try {
|
|
689
690
|
const stored = storage.getItem(key);
|
|
690
691
|
if (stored !== null) {
|
|
691
692
|
const value = deserialize(stored);
|
|
692
|
-
|
|
693
|
+
if (!validate || validate(value)) {
|
|
694
|
+
sourceSet(value);
|
|
695
|
+
}
|
|
693
696
|
}
|
|
694
697
|
} catch {
|
|
695
698
|
}
|
|
@@ -870,6 +873,9 @@ function setText(el, text) {
|
|
|
870
873
|
function setHTML(el, html) {
|
|
871
874
|
el.innerHTML = html;
|
|
872
875
|
}
|
|
876
|
+
function setHTMLUnsafe(el, html) {
|
|
877
|
+
el.innerHTML = html;
|
|
878
|
+
}
|
|
873
879
|
|
|
874
880
|
// src/dom-utils/traverse.ts
|
|
875
881
|
function closest(el, selector) {
|
|
@@ -953,20 +959,26 @@ function onMutation(el, handler, options) {
|
|
|
953
959
|
function createLocalStorage(key, options) {
|
|
954
960
|
const serialize = options?.serialize ?? JSON.stringify;
|
|
955
961
|
const deserialize = options?.deserialize ?? JSON.parse;
|
|
962
|
+
const validate = options?.validate;
|
|
956
963
|
return {
|
|
957
964
|
key,
|
|
958
965
|
get() {
|
|
959
966
|
try {
|
|
960
967
|
const raw = localStorage.getItem(key);
|
|
961
968
|
if (raw === null) return null;
|
|
962
|
-
|
|
969
|
+
const value = deserialize(raw);
|
|
970
|
+
if (validate && !validate(value)) return null;
|
|
971
|
+
return value;
|
|
963
972
|
} catch {
|
|
964
973
|
return null;
|
|
965
974
|
}
|
|
966
975
|
},
|
|
967
976
|
set(value) {
|
|
968
|
-
|
|
969
|
-
|
|
977
|
+
try {
|
|
978
|
+
const serialized = serialize(value);
|
|
979
|
+
localStorage.setItem(key, serialized);
|
|
980
|
+
} catch {
|
|
981
|
+
}
|
|
970
982
|
},
|
|
971
983
|
remove() {
|
|
972
984
|
localStorage.removeItem(key);
|
|
@@ -978,20 +990,26 @@ function createLocalStorage(key, options) {
|
|
|
978
990
|
function createSessionStorage(key, options) {
|
|
979
991
|
const serialize = options?.serialize ?? JSON.stringify;
|
|
980
992
|
const deserialize = options?.deserialize ?? JSON.parse;
|
|
993
|
+
const validate = options?.validate;
|
|
981
994
|
return {
|
|
982
995
|
key,
|
|
983
996
|
get() {
|
|
984
997
|
try {
|
|
985
998
|
const raw = sessionStorage.getItem(key);
|
|
986
999
|
if (raw === null) return null;
|
|
987
|
-
|
|
1000
|
+
const value = deserialize(raw);
|
|
1001
|
+
if (validate && !validate(value)) return null;
|
|
1002
|
+
return value;
|
|
988
1003
|
} catch {
|
|
989
1004
|
return null;
|
|
990
1005
|
}
|
|
991
1006
|
},
|
|
992
1007
|
set(value) {
|
|
993
|
-
|
|
994
|
-
|
|
1008
|
+
try {
|
|
1009
|
+
const serialized = serialize(value);
|
|
1010
|
+
sessionStorage.setItem(key, serialized);
|
|
1011
|
+
} catch {
|
|
1012
|
+
}
|
|
995
1013
|
},
|
|
996
1014
|
remove() {
|
|
997
1015
|
sessionStorage.removeItem(key);
|
|
@@ -1122,7 +1140,7 @@ function createFetch(url, options) {
|
|
|
1122
1140
|
const transformed = transform ? transform(json) : json;
|
|
1123
1141
|
setData(transformed);
|
|
1124
1142
|
} catch (err) {
|
|
1125
|
-
if (err
|
|
1143
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
1126
1144
|
return;
|
|
1127
1145
|
}
|
|
1128
1146
|
setError(err instanceof Error ? err : new Error(String(err)));
|
|
@@ -1174,13 +1192,15 @@ function createSSE(url, options) {
|
|
|
1174
1192
|
setConnected(true);
|
|
1175
1193
|
setError(null);
|
|
1176
1194
|
};
|
|
1177
|
-
|
|
1195
|
+
const parseMessage = options?.parse ?? ((raw) => {
|
|
1178
1196
|
try {
|
|
1179
|
-
|
|
1180
|
-
setData(parsed);
|
|
1197
|
+
return JSON.parse(raw);
|
|
1181
1198
|
} catch {
|
|
1182
|
-
|
|
1199
|
+
return raw;
|
|
1183
1200
|
}
|
|
1201
|
+
});
|
|
1202
|
+
source.onmessage = (event) => {
|
|
1203
|
+
setData(parseMessage(event.data));
|
|
1184
1204
|
};
|
|
1185
1205
|
source.onerror = (event) => {
|
|
1186
1206
|
setError(event);
|
|
@@ -1195,12 +1215,15 @@ function createSSE(url, options) {
|
|
|
1195
1215
|
setConnected(false);
|
|
1196
1216
|
},
|
|
1197
1217
|
on(event, handler) {
|
|
1198
|
-
const
|
|
1218
|
+
const parseEvent = options?.parse ?? ((raw) => {
|
|
1199
1219
|
try {
|
|
1200
|
-
|
|
1220
|
+
return JSON.parse(raw);
|
|
1201
1221
|
} catch {
|
|
1202
|
-
|
|
1222
|
+
return raw;
|
|
1203
1223
|
}
|
|
1224
|
+
});
|
|
1225
|
+
const listener = (e) => {
|
|
1226
|
+
handler(parseEvent(e.data));
|
|
1204
1227
|
};
|
|
1205
1228
|
source.addEventListener(event, listener);
|
|
1206
1229
|
return () => {
|
|
@@ -1230,13 +1253,15 @@ function createWebSocket(url, options) {
|
|
|
1230
1253
|
setStatus("open");
|
|
1231
1254
|
reconnectCount = 0;
|
|
1232
1255
|
};
|
|
1233
|
-
|
|
1234
|
-
let parsed;
|
|
1256
|
+
const parseMessage = options?.parse ?? ((raw) => {
|
|
1235
1257
|
try {
|
|
1236
|
-
|
|
1258
|
+
return JSON.parse(raw);
|
|
1237
1259
|
} catch {
|
|
1238
|
-
|
|
1260
|
+
return raw;
|
|
1239
1261
|
}
|
|
1262
|
+
});
|
|
1263
|
+
socket.onmessage = (event) => {
|
|
1264
|
+
const parsed = parseMessage(event.data);
|
|
1240
1265
|
setData(parsed);
|
|
1241
1266
|
for (const handler of handlers) {
|
|
1242
1267
|
handler(parsed);
|
|
@@ -1349,6 +1374,10 @@ function applyRevalidation(revalidateData) {
|
|
|
1349
1374
|
}
|
|
1350
1375
|
}
|
|
1351
1376
|
function enableAutoRevalidation() {
|
|
1377
|
+
if (typeof window === "undefined") {
|
|
1378
|
+
return () => {
|
|
1379
|
+
};
|
|
1380
|
+
}
|
|
1352
1381
|
const handler = (event) => {
|
|
1353
1382
|
const detail = event.detail;
|
|
1354
1383
|
if (detail && typeof detail === "object") {
|
|
@@ -1417,9 +1446,10 @@ async function handleRPC(endpoint, body, revalidateData) {
|
|
|
1417
1446
|
if (revalidateData) {
|
|
1418
1447
|
return { data: result, __revalidate: revalidateData };
|
|
1419
1448
|
}
|
|
1420
|
-
return result;
|
|
1449
|
+
return { data: result };
|
|
1421
1450
|
} catch (err) {
|
|
1422
|
-
const
|
|
1451
|
+
const isDev = typeof process !== "undefined" && process.env?.NODE_ENV === "development";
|
|
1452
|
+
const message = isDev && err instanceof Error ? err.message : "Internal server error";
|
|
1423
1453
|
return { error: message };
|
|
1424
1454
|
}
|
|
1425
1455
|
}
|
|
@@ -1477,6 +1507,6 @@ async function renderIsland(slotsJson, islandId) {
|
|
|
1477
1507
|
return wasm.render_island(ir, slotsJson, islandId);
|
|
1478
1508
|
}
|
|
1479
1509
|
|
|
1480
|
-
export { $, $$, $$serverFunction, activateIslands, addClass, applyRevalidation, children, closest, createAction, createBus, createContext, createErrorBoundary, createFetch, createHistory, createIndexedDB, createLocalStorage, createPortal, createRPCMiddleware, createSSE, createSessionStorage, createStore, createSuspense, createSwitch, createText, createWebSocket, defineComponent, delegate, disposeComponent, enableAutoRevalidation, fetchJSON, getRegisteredEndpoints, getServerFunction, handleRPC, inject, mount, nextSibling, onIntersect, onKey, onMount, onMutation, onResize, onUnmount, parent, persist, prevSibling, provide, registerResource, registerServerFunction, removeClass, renderIsland, renderLocal, setAttr, setHTML, setStyle, setText, siblings, toggleClass, trackDisposer, unprovide, unregisterResource, withRevalidation };
|
|
1510
|
+
export { $, $$, $$serverFunction, activateIslands, addClass, applyRevalidation, children, closest, createAction, createBus, createContext, createErrorBoundary, createFetch, createHistory, createIndexedDB, createLocalStorage, createPortal, createRPCMiddleware, createSSE, createSessionStorage, createStore, createSuspense, createSwitch, createText, createWebSocket, defineComponent, delegate, disposeComponent, enableAutoRevalidation, fetchJSON, getRegisteredEndpoints, getServerFunction, handleRPC, inject, mount, nextSibling, onIntersect, onKey, onMount, onMutation, onResize, onUnmount, parent, persist, prevSibling, provide, registerResource, registerServerFunction, removeClass, renderIsland, renderLocal, setAttr, setHTML, setHTMLUnsafe, setStyle, setText, siblings, toggleClass, trackDisposer, unprovide, unregisterResource, withRevalidation };
|
|
1481
1511
|
//# sourceMappingURL=index.js.map
|
|
1482
1512
|
//# sourceMappingURL=index.js.map
|