ilha 0.11.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +181 -784
- package/dist/index-DZI0fEmR.d.ts +374 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1667 -1816
- package/dist/internal.d.ts +61 -0
- package/dist/internal.js +39 -0
- package/dist/jsx-dev-runtime.d.ts +1 -1
- package/dist/{jsx-runtime-B-viVOB1.d.ts → jsx-runtime-BCGuHwTg.d.ts} +1 -3
- package/dist/jsx-runtime.d.ts +1 -1
- package/dist/jsx-runtime.js +11 -28
- package/package.json +7 -2
- package/dist/index-Cx35Xugv.d.ts +0 -445
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { S as NativeEventModifier, T as RawHtml, x as NativeEventHandler } from "./index-DZI0fEmR.js";
|
|
2
|
+
//#region src/internal.d.ts
|
|
3
|
+
/** Registry of live island mount handles keyed by host element. */
|
|
4
|
+
declare const ISLAND_MOUNT_HANDLES: WeakMap<Element, {
|
|
5
|
+
unmount: () => void | Promise<void>;
|
|
6
|
+
updateProps: (props?: Record<string, unknown>) => void;
|
|
7
|
+
}>;
|
|
8
|
+
/** Hook a parent's mountSlots uses to mount a child island and keep a handle
|
|
9
|
+
* for pushing updated props on later parent re-renders. */
|
|
10
|
+
declare const ISLAND_MOUNT_INTERNAL: unique symbol;
|
|
11
|
+
interface JsxEventRegistration {
|
|
12
|
+
type: string;
|
|
13
|
+
handler: NativeEventHandler;
|
|
14
|
+
modifier?: NativeEventModifier;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Bridge between the framework-agnostic JSX runtime and the active render.
|
|
18
|
+
* The core registers an implementation at module init; before that (or
|
|
19
|
+
* outside an island render) event registration yields no sentinel.
|
|
20
|
+
*/
|
|
21
|
+
interface JsxRuntimeBridge {
|
|
22
|
+
registerEvent(registration: JsxEventRegistration): number | undefined;
|
|
23
|
+
/** Compose a child-island slot marker for direct `<Island />` calls. */
|
|
24
|
+
slot(options: {
|
|
25
|
+
island: unknown;
|
|
26
|
+
props: Record<string, unknown> | undefined;
|
|
27
|
+
key: string | undefined;
|
|
28
|
+
}): RawHtml;
|
|
29
|
+
}
|
|
30
|
+
/** Register the core's bridge implementation. Internal — called once by ilha. */
|
|
31
|
+
declare function setJsxRuntimeBridge(implementation: JsxRuntimeBridge): void;
|
|
32
|
+
/** @internal Register a native event handler with the active render context. */
|
|
33
|
+
declare function __ilhaJsxEvent(registration: JsxEventRegistration): number | undefined;
|
|
34
|
+
/** @internal Preserve island slot composition from the JSX runtime. */
|
|
35
|
+
declare function __ilhaJsxSlot(options: {
|
|
36
|
+
island: unknown;
|
|
37
|
+
props: Record<string, unknown> | undefined;
|
|
38
|
+
key: string | undefined;
|
|
39
|
+
}): RawHtml;
|
|
40
|
+
/** A hydration-manifest entry: sentinel key → action id or captured payload. */
|
|
41
|
+
type ManifestEntry = string | {
|
|
42
|
+
k: string;
|
|
43
|
+
a: unknown[];
|
|
44
|
+
};
|
|
45
|
+
interface ServerManifestSerializer {
|
|
46
|
+
/**
|
|
47
|
+
* Serialize one island's event→action manifest into markup hoisted ahead of
|
|
48
|
+
* the island HTML (e.g. a `<template data-ilha-actions>` element).
|
|
49
|
+
*/
|
|
50
|
+
template(manifest: Map<string, ManifestEntry>): string;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Register the server-manifest serializer. Owned by @ilha/router — core only
|
|
54
|
+
* collects manifest data and delegates all markup serialization to the
|
|
55
|
+
* registered adapter (no-op until one registers).
|
|
56
|
+
*/
|
|
57
|
+
declare function setServerManifestSerializer(serializer: ServerManifestSerializer | null): void;
|
|
58
|
+
/** @internal Used by island rendering to serialize nested child manifests. */
|
|
59
|
+
declare function serializeServerManifest(manifest: Map<string, ManifestEntry>): string;
|
|
60
|
+
//#endregion
|
|
61
|
+
export { ISLAND_MOUNT_HANDLES, ISLAND_MOUNT_INTERNAL, JsxEventRegistration, JsxRuntimeBridge, ManifestEntry, ServerManifestSerializer, __ilhaJsxEvent, __ilhaJsxSlot, serializeServerManifest, setJsxRuntimeBridge, setServerManifestSerializer };
|
package/dist/internal.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
//#region src/internal.ts
|
|
2
|
+
/** Registry of live island mount handles keyed by host element. */
|
|
3
|
+
const ISLAND_MOUNT_HANDLES = /* @__PURE__ */ new WeakMap();
|
|
4
|
+
/** Hook a parent's mountSlots uses to mount a child island and keep a handle
|
|
5
|
+
* for pushing updated props on later parent re-renders. */
|
|
6
|
+
const ISLAND_MOUNT_INTERNAL = Symbol.for("ilha.islandMountInternal");
|
|
7
|
+
let bridge = null;
|
|
8
|
+
/** Register the core's bridge implementation. Internal — called once by ilha. */
|
|
9
|
+
function setJsxRuntimeBridge(implementation) {
|
|
10
|
+
bridge = implementation;
|
|
11
|
+
}
|
|
12
|
+
/** @internal Register a native event handler with the active render context. */
|
|
13
|
+
function __ilhaJsxEvent(registration) {
|
|
14
|
+
return bridge?.registerEvent(registration);
|
|
15
|
+
}
|
|
16
|
+
/** @internal Preserve island slot composition from the JSX runtime. */
|
|
17
|
+
function __ilhaJsxSlot(options) {
|
|
18
|
+
return bridge?.slot(options) ?? {
|
|
19
|
+
[Symbol.for("ilha.raw")]: true,
|
|
20
|
+
value: ""
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
let serverManifestSerializer = null;
|
|
24
|
+
/**
|
|
25
|
+
* Register the server-manifest serializer. Owned by @ilha/router — core only
|
|
26
|
+
* collects manifest data and delegates all markup serialization to the
|
|
27
|
+
* registered adapter (no-op until one registers).
|
|
28
|
+
*/
|
|
29
|
+
function setServerManifestSerializer(serializer) {
|
|
30
|
+
serverManifestSerializer = serializer;
|
|
31
|
+
}
|
|
32
|
+
/** @internal Used by island rendering to serialize nested child manifests. */
|
|
33
|
+
function serializeServerManifest(manifest) {
|
|
34
|
+
if (!serverManifestSerializer || manifest.size === 0) return "";
|
|
35
|
+
return serverManifestSerializer.template(manifest);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
//#endregion
|
|
39
|
+
export { ISLAND_MOUNT_HANDLES, ISLAND_MOUNT_INTERNAL, __ilhaJsxEvent, __ilhaJsxSlot, serializeServerManifest, setJsxRuntimeBridge, setServerManifestSerializer };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as JSX, r as jsxDEV, t as Fragment } from "./jsx-runtime-
|
|
1
|
+
import { a as JSX, r as jsxDEV, t as Fragment } from "./jsx-runtime-BCGuHwTg.js";
|
|
2
2
|
export { Fragment, type JSX, jsxDEV };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { E as SignalAccessor, O as SignalWriter, S as NativeEventModifier, T as RawHtml, x as NativeEventHandler } from "./index-DZI0fEmR.js";
|
|
2
2
|
//#region src/jsx-types.d.ts
|
|
3
3
|
declare namespace JSX {
|
|
4
4
|
export type Child = unknown;
|
|
@@ -200,8 +200,6 @@ declare namespace JSX {
|
|
|
200
200
|
value?: string | number;
|
|
201
201
|
width?: Numberish;
|
|
202
202
|
"bind:value"?: BindAccessor<string | number>;
|
|
203
|
-
"bind:valueAsNumber"?: BindAccessor<number | null>;
|
|
204
|
-
"bind:valueAsDate"?: BindAccessor<Date | null>;
|
|
205
203
|
"bind:checked"?: BindAccessor<boolean>;
|
|
206
204
|
"bind:group"?: BindAccessor<string | number | Array<string | number>>;
|
|
207
205
|
"bind:files"?: BindAccessor<FileList | null>;
|
package/dist/jsx-runtime.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as JSX, i as jsxs, n as jsx, r as jsxDEV, t as Fragment } from "./jsx-runtime-
|
|
1
|
+
import { a as JSX, i as jsxs, n as jsx, r as jsxDEV, t as Fragment } from "./jsx-runtime-BCGuHwTg.js";
|
|
2
2
|
export { Fragment, type JSX, jsx, jsxDEV, jsxs };
|
package/dist/jsx-runtime.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
import { __ilhaJsxEvent, __ilhaJsxSlot
|
|
1
|
+
import { __ilhaJsxEvent, __ilhaJsxSlot } from "./internal.js";
|
|
2
|
+
import { html, isSafeUrlAttrValue, isUrlAttributeName, raw, serializeStyle } from "./index.js";
|
|
2
3
|
|
|
3
4
|
//#region src/jsx-runtime.ts
|
|
5
|
+
function toTemplateStrings(chunks) {
|
|
6
|
+
return Object.assign(chunks, { raw: chunks });
|
|
7
|
+
}
|
|
4
8
|
const RAW = Symbol.for("ilha.raw");
|
|
5
9
|
const SIGNAL_ACCESSOR = Symbol.for("ilha.signalAccessor");
|
|
6
10
|
const ISLAND = Symbol.for("ilha.island");
|
|
@@ -65,20 +69,6 @@ const VOID_ELEMENTS = /* @__PURE__ */ new Set([
|
|
|
65
69
|
"track",
|
|
66
70
|
"wbr"
|
|
67
71
|
]);
|
|
68
|
-
const SAFE_CSS_PROP_RE = /^(-{2}[a-zA-Z][a-zA-Z0-9-]*|-?[a-zA-Z][a-zA-Z0-9-]*)$/;
|
|
69
|
-
const URL_ATTRS = /* @__PURE__ */ new Set([
|
|
70
|
-
"href",
|
|
71
|
-
"src",
|
|
72
|
-
"action",
|
|
73
|
-
"formaction",
|
|
74
|
-
"cite",
|
|
75
|
-
"data",
|
|
76
|
-
"poster"
|
|
77
|
-
]);
|
|
78
|
-
const SAFE_URL_RE = /^(?!javascript:|data:text\/html|data:text\/xml|data:application\/xhtml\+xml|data:image\/svg|vbscript:)/i;
|
|
79
|
-
function isSafeUrl(value) {
|
|
80
|
-
return SAFE_URL_RE.test(value.replace(/[\u0000-\u0020]/g, ""));
|
|
81
|
-
}
|
|
82
72
|
function isRawHtml(v) {
|
|
83
73
|
return !!(v && typeof v === "object" && RAW in v);
|
|
84
74
|
}
|
|
@@ -114,16 +104,7 @@ function extractJsxSlotKey(props, keyArg) {
|
|
|
114
104
|
if (rawKey == null) return void 0;
|
|
115
105
|
return normalizeJsxSlotKey(rawKey);
|
|
116
106
|
}
|
|
117
|
-
function
|
|
118
|
-
return Object.entries(value).map(([k, v]) => {
|
|
119
|
-
if (!SAFE_CSS_PROP_RE.test(k)) return "";
|
|
120
|
-
const prop = k.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
|
|
121
|
-
const str = String(v);
|
|
122
|
-
if (/[<>{};]/.test(str) || /expression\(/i.test(str) || /javascript:/i.test(str)) return "";
|
|
123
|
-
return `${prop}:${str}`;
|
|
124
|
-
}).filter(Boolean).join(";");
|
|
125
|
-
}
|
|
126
|
-
function pushJsxAttr({ chunks, values, eventSpecs, name, value }) {
|
|
107
|
+
function pushJsxAttr({ chunks, values, eventSpecs, tagName, name, value }) {
|
|
127
108
|
if (value == null || name === "children" || name === "key") return;
|
|
128
109
|
if (name === "__proto__" || name === "constructor" || name === "prototype") return;
|
|
129
110
|
if (name.startsWith("bind:")) {
|
|
@@ -157,7 +138,7 @@ function pushJsxAttr({ chunks, values, eventSpecs, name, value }) {
|
|
|
157
138
|
else if (value === false) return;
|
|
158
139
|
if (safeName === "class" && !isRawHtml(value)) value = normalizeClass(value);
|
|
159
140
|
if (safeName === "style" && value && typeof value === "object" && !isRawHtml(value)) value = serializeStyle(value);
|
|
160
|
-
if ((
|
|
141
|
+
if (isUrlAttributeName(securityName) && !isSafeUrlAttrValue(tagName, securityName, typeof value === "string" ? value : String(value))) return;
|
|
161
142
|
if (value === true) {
|
|
162
143
|
chunks[chunks.length - 1] += ` ${safeName}`;
|
|
163
144
|
return;
|
|
@@ -186,6 +167,7 @@ function renderJsxElement({ type, props, children, slotKey }) {
|
|
|
186
167
|
chunks,
|
|
187
168
|
values,
|
|
188
169
|
eventSpecs,
|
|
170
|
+
tagName: type,
|
|
189
171
|
name,
|
|
190
172
|
value
|
|
191
173
|
});
|
|
@@ -193,6 +175,7 @@ function renderJsxElement({ type, props, children, slotKey }) {
|
|
|
193
175
|
chunks,
|
|
194
176
|
values,
|
|
195
177
|
eventSpecs,
|
|
178
|
+
tagName: type,
|
|
196
179
|
name: "data-key",
|
|
197
180
|
value: slotKey
|
|
198
181
|
});
|
|
@@ -205,7 +188,7 @@ function renderJsxElement({ type, props, children, slotKey }) {
|
|
|
205
188
|
}
|
|
206
189
|
chunks[chunks.length - 1] += `</${type}>`;
|
|
207
190
|
}
|
|
208
|
-
return html(chunks, ...values);
|
|
191
|
+
return html(toTemplateStrings(chunks), ...values);
|
|
209
192
|
}
|
|
210
193
|
function jsx(type, props, maybeKey, ...restChildren) {
|
|
211
194
|
const hasKeyArg = typeof maybeKey === "string" || typeof maybeKey === "number";
|
|
@@ -244,7 +227,7 @@ const jsxs = jsx;
|
|
|
244
227
|
function Fragment(props, ...children) {
|
|
245
228
|
const normalizedChildren = normalizeJsxChildren(props, children);
|
|
246
229
|
const chunks = ["", ...normalizedChildren.map(() => "")];
|
|
247
|
-
return html(chunks, ...normalizedChildren);
|
|
230
|
+
return html(toTemplateStrings(chunks), ...normalizedChildren);
|
|
248
231
|
}
|
|
249
232
|
function jsxDEV(type, props, maybeKey, _source, _self) {
|
|
250
233
|
return jsx(type, props, maybeKey);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ilha",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "A tiny, framework-free island architecture library",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"framework-free",
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
],
|
|
30
30
|
"type": "module",
|
|
31
31
|
"sideEffects": false,
|
|
32
|
+
"main": "./dist/index.js",
|
|
32
33
|
"module": "./dist/index.js",
|
|
33
34
|
"browser": {
|
|
34
35
|
"process": false
|
|
@@ -46,13 +47,17 @@
|
|
|
46
47
|
"./jsx-dev-runtime": {
|
|
47
48
|
"types": "./dist/jsx-dev-runtime.d.ts",
|
|
48
49
|
"import": "./dist/jsx-dev-runtime.js"
|
|
50
|
+
},
|
|
51
|
+
"./internal": {
|
|
52
|
+
"types": "./dist/internal.d.ts",
|
|
53
|
+
"import": "./dist/internal.js"
|
|
49
54
|
}
|
|
50
55
|
},
|
|
51
56
|
"publishConfig": {
|
|
52
57
|
"access": "public"
|
|
53
58
|
},
|
|
54
59
|
"scripts": {
|
|
55
|
-
"build": "tsc && tsdown",
|
|
60
|
+
"build": "tsc -p tsconfig.build.json && tsdown",
|
|
56
61
|
"cleanup": "rimraf dist node_modules",
|
|
57
62
|
"test": "bun test"
|
|
58
63
|
},
|