@solidjs/web 2.0.0-beta.26 → 2.0.0-beta.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dev.cjs +3 -1
- package/dist/dev.js +3 -2
- package/dist/server.cjs +41 -78
- package/dist/server.js +42 -80
- package/dist/web.cjs +3 -1
- package/dist/web.js +3 -2
- package/frames/dist/client.cjs +69 -21
- package/frames/dist/client.dev.cjs +69 -21
- package/frames/dist/client.dev.js +70 -22
- package/frames/dist/client.js +70 -22
- package/frames/dist/server.cjs +33 -45
- package/frames/dist/server.js +33 -45
- package/package.json +4 -4
- package/serialization/dist/serialization.cjs +6 -3
- package/serialization/dist/serialization.js +6 -3
- package/serialization/types/index.d.ts +7 -1
- package/serialization/types-cjs/index.d.cts +7 -1
- package/server-functions/dist/client.cjs +15 -2
- package/server-functions/dist/client.js +13 -3
- package/server-functions/dist/server.cjs +161 -5
- package/server-functions/dist/server.js +155 -6
- package/types/client.d.ts +3 -3
- package/types/frames/serializer.d.ts +7 -1
- package/types/jsx.d.ts +1 -1
- package/types/response.d.ts +10 -0
- package/types/serializer.d.ts +7 -1
- package/types/server-functions/client.d.ts +3 -0
- package/types/server-functions/flash.d.ts +38 -0
- package/types/server-functions/server.d.ts +79 -4
- package/types/server-functions/shared.d.ts +35 -0
- package/types-cjs/client.d.cts +3 -3
- package/types-cjs/frames/serializer.d.cts +7 -1
- package/types-cjs/jsx.d.cts +1 -1
- package/types-cjs/response.d.cts +10 -0
- package/types-cjs/serializer.d.cts +7 -1
- package/types-cjs/server-functions/client.d.cts +3 -0
- package/types-cjs/server-functions/flash.d.cts +38 -0
- package/types-cjs/server-functions/server.d.cts +79 -4
- package/types-cjs/server-functions/shared.d.cts +35 -0
package/frames/dist/client.cjs
CHANGED
|
@@ -114,7 +114,7 @@ function createFrameHost(options = {}) {
|
|
|
114
114
|
pending.delete(id);
|
|
115
115
|
const records = {};
|
|
116
116
|
let version;
|
|
117
|
-
for (const chunk of buffered) {
|
|
117
|
+
for (const chunk of buffered.chunks) {
|
|
118
118
|
if (chunk.type === "data") {
|
|
119
119
|
options.applyData && options.applyData(chunk);
|
|
120
120
|
continue;
|
|
@@ -146,12 +146,20 @@ function createFrameHost(options = {}) {
|
|
|
146
146
|
for (const frame of set) deliver(frame, chunk);
|
|
147
147
|
return;
|
|
148
148
|
}
|
|
149
|
-
const buffered = pending.get(chunk.id)
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
149
|
+
const buffered = pending.get(chunk.id);
|
|
150
|
+
if (!buffered) {
|
|
151
|
+
pending.set(chunk.id, {
|
|
152
|
+
version: chunk.version,
|
|
153
|
+
chunks: [chunk]
|
|
154
|
+
});
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
if (chunk.version < buffered.version) return;
|
|
158
|
+
if (chunk.version > buffered.version) {
|
|
159
|
+
buffered.version = chunk.version;
|
|
160
|
+
buffered.chunks.length = 0;
|
|
161
|
+
}
|
|
162
|
+
buffered.chunks.push(chunk);
|
|
155
163
|
},
|
|
156
164
|
get(id) {
|
|
157
165
|
const set = frames.get(id);
|
|
@@ -210,7 +218,7 @@ class FrameImpl {
|
|
|
210
218
|
if (options.host && options.id !== undefined) {
|
|
211
219
|
options.host.register(options.id, this);
|
|
212
220
|
}
|
|
213
|
-
if (options.adopt) this.#syncSlots();
|
|
221
|
+
if (options.adopt && this.#version === undefined) this.#syncSlots();
|
|
214
222
|
}
|
|
215
223
|
#parent() {
|
|
216
224
|
return this.#element ?? this.#start.parentNode;
|
|
@@ -354,7 +362,7 @@ class FrameImpl {
|
|
|
354
362
|
if (nodes) this.#replaceRange(occurrence, start, nodes);
|
|
355
363
|
this.#slotNodes.set(occurrence, nodes);
|
|
356
364
|
this.#mountedSlots.add(occurrence);
|
|
357
|
-
this.#discoverRegions(occurrence, start);
|
|
365
|
+
if (!this.#options.adopt || nodes) this.#discoverRegions(occurrence, start);
|
|
358
366
|
this.#bindRegions(occurrence);
|
|
359
367
|
} else if (record !== this.#slotArgs.get(occurrence)) {
|
|
360
368
|
if (this.#refArgsUnchanged(occurrence, record)) {
|
|
@@ -1226,15 +1234,18 @@ function normalizeSlotContent(value) {
|
|
|
1226
1234
|
if (value == null || typeof value === "boolean") return document.createTextNode("");
|
|
1227
1235
|
return value instanceof Node ? value : document.createTextNode(String(value));
|
|
1228
1236
|
}
|
|
1237
|
+
function gatherClaims(el, registry) {
|
|
1238
|
+
if (el.hasAttribute("_hk")) registry.set(el.getAttribute("_hk"), el);
|
|
1239
|
+
if (el.hasAttribute(FRAME_ID_ATTR)) return;
|
|
1240
|
+
for (let c = el.firstElementChild; c; c = c.nextElementSibling) gatherClaims(c, registry);
|
|
1241
|
+
}
|
|
1229
1242
|
function claimRender(prefix, existing, render) {
|
|
1230
1243
|
const sc = solidJs.sharedConfig;
|
|
1231
1244
|
if (!sc.getNextContextId) return render();
|
|
1232
1245
|
const registry = new Map();
|
|
1233
1246
|
for (const n of existing) {
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
if (el.hasAttribute("_hk")) registry.set(el.getAttribute("_hk"), el);
|
|
1237
|
-
el.querySelectorAll("*[_hk]").forEach(child => registry.set(child.getAttribute("_hk"), child));
|
|
1247
|
+
if (n.nodeType !== 1) continue;
|
|
1248
|
+
gatherClaims(n, registry);
|
|
1238
1249
|
}
|
|
1239
1250
|
if (!registry.size) return render();
|
|
1240
1251
|
const prevRegistry = sc.registry;
|
|
@@ -1298,21 +1309,57 @@ function boundaryComponent(host, id) {
|
|
|
1298
1309
|
}
|
|
1299
1310
|
const claimedBoundaries = new Set();
|
|
1300
1311
|
let boundaryIndex = null;
|
|
1312
|
+
const isBoundaryId = id => !id.includes(".");
|
|
1313
|
+
function indexBoundaries(root) {
|
|
1314
|
+
root.querySelectorAll(`[${FRAME_ID_ATTR}]`).forEach(el => {
|
|
1315
|
+
const key = el.getAttribute(FRAME_ID_ATTR);
|
|
1316
|
+
if (key && isBoundaryId(key) && !boundaryIndex.has(key)) boundaryIndex.set(key, el);
|
|
1317
|
+
});
|
|
1318
|
+
}
|
|
1301
1319
|
function findBoundaryElement(id) {
|
|
1302
1320
|
if (!boundaryIndex) {
|
|
1303
1321
|
boundaryIndex = new Map();
|
|
1304
|
-
if (typeof document !== "undefined" && document.body)
|
|
1305
|
-
document.body.querySelectorAll(`[${FRAME_ID_ATTR}]`).forEach(el => {
|
|
1306
|
-
const key = el.getAttribute(FRAME_ID_ATTR);
|
|
1307
|
-
if (key && !boundaryIndex.has(key)) boundaryIndex.set(key, el);
|
|
1308
|
-
});
|
|
1309
|
-
}
|
|
1322
|
+
if (typeof document !== "undefined" && document.body) indexBoundaries(document.body);
|
|
1310
1323
|
}
|
|
1311
1324
|
return boundaryIndex.get(id);
|
|
1312
1325
|
}
|
|
1326
|
+
const boundaryWaiters = new Map();
|
|
1327
|
+
function documentStreaming() {
|
|
1328
|
+
const hy = globalThis._$HY;
|
|
1329
|
+
return !!hy && !hy.done;
|
|
1330
|
+
}
|
|
1331
|
+
function installRevealHook() {
|
|
1332
|
+
const hy = globalThis._$HY;
|
|
1333
|
+
if (!hy || hy.$sc) return;
|
|
1334
|
+
hy.$sc = true;
|
|
1335
|
+
const prev = hy.fe;
|
|
1336
|
+
hy.fe = (fragmentId, parent) => {
|
|
1337
|
+
if (prev) prev(fragmentId, parent);
|
|
1338
|
+
if (!boundaryIndex) return;
|
|
1339
|
+
const root = parent || (typeof document !== "undefined" ? document.body : null);
|
|
1340
|
+
if (!root) return;
|
|
1341
|
+
indexBoundaries(root);
|
|
1342
|
+
for (const [id, notify] of boundaryWaiters) {
|
|
1343
|
+
const el = boundaryIndex.get(id);
|
|
1344
|
+
if (!el) continue;
|
|
1345
|
+
boundaryWaiters.delete(id);
|
|
1346
|
+
notify(el);
|
|
1347
|
+
}
|
|
1348
|
+
};
|
|
1349
|
+
}
|
|
1313
1350
|
function documentBoundary(host, id, props) {
|
|
1314
|
-
const
|
|
1315
|
-
|
|
1351
|
+
const claimed = claimedBoundaries.has(id);
|
|
1352
|
+
const el = !claimed ? findBoundaryElement(id) : undefined;
|
|
1353
|
+
if (el) return adoptBoundary(host, id, el, props);
|
|
1354
|
+
if (!claimed && !boundaryWaiters.has(id) && documentStreaming()) {
|
|
1355
|
+
const owner = solidJs.getOwner();
|
|
1356
|
+
const arrival = new Promise(resolve => boundaryWaiters.set(id, resolve));
|
|
1357
|
+
solidJs.onCleanup(() => boundaryWaiters.delete(id));
|
|
1358
|
+
return solidJs.createMemo(() => arrival.then(node => solidJs.runWithOwner(owner, () => adoptBoundary(host, id, node, props))));
|
|
1359
|
+
}
|
|
1360
|
+
return boundaryComponent(host, id)(props);
|
|
1361
|
+
}
|
|
1362
|
+
function adoptBoundary(host, id, el, props) {
|
|
1316
1363
|
claimedBoundaries.add(id);
|
|
1317
1364
|
const hy = globalThis._$HY;
|
|
1318
1365
|
if (hy && hy.r) {
|
|
@@ -1364,6 +1411,7 @@ function installServerComponents(host = getFrameHost()) {
|
|
|
1364
1411
|
};
|
|
1365
1412
|
}
|
|
1366
1413
|
g._$SC.impl = (id, props) => documentBoundary(host, id, props);
|
|
1414
|
+
installRevealHook();
|
|
1367
1415
|
client.configureServerFunctionsClient({
|
|
1368
1416
|
responseHandler: createServerComponentHandler({
|
|
1369
1417
|
host,
|
|
@@ -114,7 +114,7 @@ function createFrameHost(options = {}) {
|
|
|
114
114
|
pending.delete(id);
|
|
115
115
|
const records = {};
|
|
116
116
|
let version;
|
|
117
|
-
for (const chunk of buffered) {
|
|
117
|
+
for (const chunk of buffered.chunks) {
|
|
118
118
|
if (chunk.type === "data") {
|
|
119
119
|
options.applyData && options.applyData(chunk);
|
|
120
120
|
continue;
|
|
@@ -146,12 +146,20 @@ function createFrameHost(options = {}) {
|
|
|
146
146
|
for (const frame of set) deliver(frame, chunk);
|
|
147
147
|
return;
|
|
148
148
|
}
|
|
149
|
-
const buffered = pending.get(chunk.id)
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
149
|
+
const buffered = pending.get(chunk.id);
|
|
150
|
+
if (!buffered) {
|
|
151
|
+
pending.set(chunk.id, {
|
|
152
|
+
version: chunk.version,
|
|
153
|
+
chunks: [chunk]
|
|
154
|
+
});
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
if (chunk.version < buffered.version) return;
|
|
158
|
+
if (chunk.version > buffered.version) {
|
|
159
|
+
buffered.version = chunk.version;
|
|
160
|
+
buffered.chunks.length = 0;
|
|
161
|
+
}
|
|
162
|
+
buffered.chunks.push(chunk);
|
|
155
163
|
},
|
|
156
164
|
get(id) {
|
|
157
165
|
const set = frames.get(id);
|
|
@@ -210,7 +218,7 @@ class FrameImpl {
|
|
|
210
218
|
if (options.host && options.id !== undefined) {
|
|
211
219
|
options.host.register(options.id, this);
|
|
212
220
|
}
|
|
213
|
-
if (options.adopt) this.#syncSlots();
|
|
221
|
+
if (options.adopt && this.#version === undefined) this.#syncSlots();
|
|
214
222
|
}
|
|
215
223
|
#parent() {
|
|
216
224
|
return this.#element ?? this.#start.parentNode;
|
|
@@ -354,7 +362,7 @@ class FrameImpl {
|
|
|
354
362
|
if (nodes) this.#replaceRange(occurrence, start, nodes);
|
|
355
363
|
this.#slotNodes.set(occurrence, nodes);
|
|
356
364
|
this.#mountedSlots.add(occurrence);
|
|
357
|
-
this.#discoverRegions(occurrence, start);
|
|
365
|
+
if (!this.#options.adopt || nodes) this.#discoverRegions(occurrence, start);
|
|
358
366
|
this.#bindRegions(occurrence);
|
|
359
367
|
} else if (record !== this.#slotArgs.get(occurrence)) {
|
|
360
368
|
if (this.#refArgsUnchanged(occurrence, record)) {
|
|
@@ -1240,15 +1248,18 @@ function normalizeSlotContent(value) {
|
|
|
1240
1248
|
if (value == null || typeof value === "boolean") return document.createTextNode("");
|
|
1241
1249
|
return value instanceof Node ? value : document.createTextNode(String(value));
|
|
1242
1250
|
}
|
|
1251
|
+
function gatherClaims(el, registry) {
|
|
1252
|
+
if (el.hasAttribute("_hk")) registry.set(el.getAttribute("_hk"), el);
|
|
1253
|
+
if (el.hasAttribute(FRAME_ID_ATTR)) return;
|
|
1254
|
+
for (let c = el.firstElementChild; c; c = c.nextElementSibling) gatherClaims(c, registry);
|
|
1255
|
+
}
|
|
1243
1256
|
function claimRender(prefix, existing, render) {
|
|
1244
1257
|
const sc = solidJs.sharedConfig;
|
|
1245
1258
|
if (!sc.getNextContextId) return render();
|
|
1246
1259
|
const registry = new Map();
|
|
1247
1260
|
for (const n of existing) {
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
if (el.hasAttribute("_hk")) registry.set(el.getAttribute("_hk"), el);
|
|
1251
|
-
el.querySelectorAll("*[_hk]").forEach(child => registry.set(child.getAttribute("_hk"), child));
|
|
1261
|
+
if (n.nodeType !== 1) continue;
|
|
1262
|
+
gatherClaims(n, registry);
|
|
1252
1263
|
}
|
|
1253
1264
|
if (!registry.size) return render();
|
|
1254
1265
|
const prevRegistry = sc.registry;
|
|
@@ -1312,21 +1323,57 @@ function boundaryComponent(host, id) {
|
|
|
1312
1323
|
}
|
|
1313
1324
|
const claimedBoundaries = new Set();
|
|
1314
1325
|
let boundaryIndex = null;
|
|
1326
|
+
const isBoundaryId = id => !id.includes(".");
|
|
1327
|
+
function indexBoundaries(root) {
|
|
1328
|
+
root.querySelectorAll(`[${FRAME_ID_ATTR}]`).forEach(el => {
|
|
1329
|
+
const key = el.getAttribute(FRAME_ID_ATTR);
|
|
1330
|
+
if (key && isBoundaryId(key) && !boundaryIndex.has(key)) boundaryIndex.set(key, el);
|
|
1331
|
+
});
|
|
1332
|
+
}
|
|
1315
1333
|
function findBoundaryElement(id) {
|
|
1316
1334
|
if (!boundaryIndex) {
|
|
1317
1335
|
boundaryIndex = new Map();
|
|
1318
|
-
if (typeof document !== "undefined" && document.body)
|
|
1319
|
-
document.body.querySelectorAll(`[${FRAME_ID_ATTR}]`).forEach(el => {
|
|
1320
|
-
const key = el.getAttribute(FRAME_ID_ATTR);
|
|
1321
|
-
if (key && !boundaryIndex.has(key)) boundaryIndex.set(key, el);
|
|
1322
|
-
});
|
|
1323
|
-
}
|
|
1336
|
+
if (typeof document !== "undefined" && document.body) indexBoundaries(document.body);
|
|
1324
1337
|
}
|
|
1325
1338
|
return boundaryIndex.get(id);
|
|
1326
1339
|
}
|
|
1340
|
+
const boundaryWaiters = new Map();
|
|
1341
|
+
function documentStreaming() {
|
|
1342
|
+
const hy = globalThis._$HY;
|
|
1343
|
+
return !!hy && !hy.done;
|
|
1344
|
+
}
|
|
1345
|
+
function installRevealHook() {
|
|
1346
|
+
const hy = globalThis._$HY;
|
|
1347
|
+
if (!hy || hy.$sc) return;
|
|
1348
|
+
hy.$sc = true;
|
|
1349
|
+
const prev = hy.fe;
|
|
1350
|
+
hy.fe = (fragmentId, parent) => {
|
|
1351
|
+
if (prev) prev(fragmentId, parent);
|
|
1352
|
+
if (!boundaryIndex) return;
|
|
1353
|
+
const root = parent || (typeof document !== "undefined" ? document.body : null);
|
|
1354
|
+
if (!root) return;
|
|
1355
|
+
indexBoundaries(root);
|
|
1356
|
+
for (const [id, notify] of boundaryWaiters) {
|
|
1357
|
+
const el = boundaryIndex.get(id);
|
|
1358
|
+
if (!el) continue;
|
|
1359
|
+
boundaryWaiters.delete(id);
|
|
1360
|
+
notify(el);
|
|
1361
|
+
}
|
|
1362
|
+
};
|
|
1363
|
+
}
|
|
1327
1364
|
function documentBoundary(host, id, props) {
|
|
1328
|
-
const
|
|
1329
|
-
|
|
1365
|
+
const claimed = claimedBoundaries.has(id);
|
|
1366
|
+
const el = !claimed ? findBoundaryElement(id) : undefined;
|
|
1367
|
+
if (el) return adoptBoundary(host, id, el, props);
|
|
1368
|
+
if (!claimed && !boundaryWaiters.has(id) && documentStreaming()) {
|
|
1369
|
+
const owner = solidJs.getOwner();
|
|
1370
|
+
const arrival = new Promise(resolve => boundaryWaiters.set(id, resolve));
|
|
1371
|
+
solidJs.onCleanup(() => boundaryWaiters.delete(id));
|
|
1372
|
+
return solidJs.createMemo(() => arrival.then(node => solidJs.runWithOwner(owner, () => adoptBoundary(host, id, node, props))));
|
|
1373
|
+
}
|
|
1374
|
+
return boundaryComponent(host, id)(props);
|
|
1375
|
+
}
|
|
1376
|
+
function adoptBoundary(host, id, el, props) {
|
|
1330
1377
|
claimedBoundaries.add(id);
|
|
1331
1378
|
const hy = globalThis._$HY;
|
|
1332
1379
|
if (hy && hy.r) {
|
|
@@ -1378,6 +1425,7 @@ function installServerComponents(host = getFrameHost()) {
|
|
|
1378
1425
|
};
|
|
1379
1426
|
}
|
|
1380
1427
|
g._$SC.impl = (id, props) => documentBoundary(host, id, props);
|
|
1428
|
+
installRevealHook();
|
|
1381
1429
|
client.configureServerFunctionsClient({
|
|
1382
1430
|
responseHandler: createServerComponentHandler({
|
|
1383
1431
|
host,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getOwner,
|
|
1
|
+
import { getOwner, onCleanup, createMemo, runWithOwner, createLoadingBoundary, sharedConfig, createOwner } from 'solid-js';
|
|
2
2
|
import { insert } from '@solidjs/web';
|
|
3
3
|
import { configureServerFunctionsClient } from '@solidjs/web/server-functions/client';
|
|
4
4
|
import { fromCrossJSON, Feature } from 'seroval';
|
|
@@ -112,7 +112,7 @@ function createFrameHost(options = {}) {
|
|
|
112
112
|
pending.delete(id);
|
|
113
113
|
const records = {};
|
|
114
114
|
let version;
|
|
115
|
-
for (const chunk of buffered) {
|
|
115
|
+
for (const chunk of buffered.chunks) {
|
|
116
116
|
if (chunk.type === "data") {
|
|
117
117
|
options.applyData && options.applyData(chunk);
|
|
118
118
|
continue;
|
|
@@ -144,12 +144,20 @@ function createFrameHost(options = {}) {
|
|
|
144
144
|
for (const frame of set) deliver(frame, chunk);
|
|
145
145
|
return;
|
|
146
146
|
}
|
|
147
|
-
const buffered = pending.get(chunk.id)
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
147
|
+
const buffered = pending.get(chunk.id);
|
|
148
|
+
if (!buffered) {
|
|
149
|
+
pending.set(chunk.id, {
|
|
150
|
+
version: chunk.version,
|
|
151
|
+
chunks: [chunk]
|
|
152
|
+
});
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
if (chunk.version < buffered.version) return;
|
|
156
|
+
if (chunk.version > buffered.version) {
|
|
157
|
+
buffered.version = chunk.version;
|
|
158
|
+
buffered.chunks.length = 0;
|
|
159
|
+
}
|
|
160
|
+
buffered.chunks.push(chunk);
|
|
153
161
|
},
|
|
154
162
|
get(id) {
|
|
155
163
|
const set = frames.get(id);
|
|
@@ -208,7 +216,7 @@ class FrameImpl {
|
|
|
208
216
|
if (options.host && options.id !== undefined) {
|
|
209
217
|
options.host.register(options.id, this);
|
|
210
218
|
}
|
|
211
|
-
if (options.adopt) this.#syncSlots();
|
|
219
|
+
if (options.adopt && this.#version === undefined) this.#syncSlots();
|
|
212
220
|
}
|
|
213
221
|
#parent() {
|
|
214
222
|
return this.#element ?? this.#start.parentNode;
|
|
@@ -352,7 +360,7 @@ class FrameImpl {
|
|
|
352
360
|
if (nodes) this.#replaceRange(occurrence, start, nodes);
|
|
353
361
|
this.#slotNodes.set(occurrence, nodes);
|
|
354
362
|
this.#mountedSlots.add(occurrence);
|
|
355
|
-
this.#discoverRegions(occurrence, start);
|
|
363
|
+
if (!this.#options.adopt || nodes) this.#discoverRegions(occurrence, start);
|
|
356
364
|
this.#bindRegions(occurrence);
|
|
357
365
|
} else if (record !== this.#slotArgs.get(occurrence)) {
|
|
358
366
|
if (this.#refArgsUnchanged(occurrence, record)) {
|
|
@@ -1238,15 +1246,18 @@ function normalizeSlotContent(value) {
|
|
|
1238
1246
|
if (value == null || typeof value === "boolean") return document.createTextNode("");
|
|
1239
1247
|
return value instanceof Node ? value : document.createTextNode(String(value));
|
|
1240
1248
|
}
|
|
1249
|
+
function gatherClaims(el, registry) {
|
|
1250
|
+
if (el.hasAttribute("_hk")) registry.set(el.getAttribute("_hk"), el);
|
|
1251
|
+
if (el.hasAttribute(FRAME_ID_ATTR)) return;
|
|
1252
|
+
for (let c = el.firstElementChild; c; c = c.nextElementSibling) gatherClaims(c, registry);
|
|
1253
|
+
}
|
|
1241
1254
|
function claimRender(prefix, existing, render) {
|
|
1242
1255
|
const sc = sharedConfig;
|
|
1243
1256
|
if (!sc.getNextContextId) return render();
|
|
1244
1257
|
const registry = new Map();
|
|
1245
1258
|
for (const n of existing) {
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
if (el.hasAttribute("_hk")) registry.set(el.getAttribute("_hk"), el);
|
|
1249
|
-
el.querySelectorAll("*[_hk]").forEach(child => registry.set(child.getAttribute("_hk"), child));
|
|
1259
|
+
if (n.nodeType !== 1) continue;
|
|
1260
|
+
gatherClaims(n, registry);
|
|
1250
1261
|
}
|
|
1251
1262
|
if (!registry.size) return render();
|
|
1252
1263
|
const prevRegistry = sc.registry;
|
|
@@ -1310,21 +1321,57 @@ function boundaryComponent(host, id) {
|
|
|
1310
1321
|
}
|
|
1311
1322
|
const claimedBoundaries = new Set();
|
|
1312
1323
|
let boundaryIndex = null;
|
|
1324
|
+
const isBoundaryId = id => !id.includes(".");
|
|
1325
|
+
function indexBoundaries(root) {
|
|
1326
|
+
root.querySelectorAll(`[${FRAME_ID_ATTR}]`).forEach(el => {
|
|
1327
|
+
const key = el.getAttribute(FRAME_ID_ATTR);
|
|
1328
|
+
if (key && isBoundaryId(key) && !boundaryIndex.has(key)) boundaryIndex.set(key, el);
|
|
1329
|
+
});
|
|
1330
|
+
}
|
|
1313
1331
|
function findBoundaryElement(id) {
|
|
1314
1332
|
if (!boundaryIndex) {
|
|
1315
1333
|
boundaryIndex = new Map();
|
|
1316
|
-
if (typeof document !== "undefined" && document.body)
|
|
1317
|
-
document.body.querySelectorAll(`[${FRAME_ID_ATTR}]`).forEach(el => {
|
|
1318
|
-
const key = el.getAttribute(FRAME_ID_ATTR);
|
|
1319
|
-
if (key && !boundaryIndex.has(key)) boundaryIndex.set(key, el);
|
|
1320
|
-
});
|
|
1321
|
-
}
|
|
1334
|
+
if (typeof document !== "undefined" && document.body) indexBoundaries(document.body);
|
|
1322
1335
|
}
|
|
1323
1336
|
return boundaryIndex.get(id);
|
|
1324
1337
|
}
|
|
1338
|
+
const boundaryWaiters = new Map();
|
|
1339
|
+
function documentStreaming() {
|
|
1340
|
+
const hy = globalThis._$HY;
|
|
1341
|
+
return !!hy && !hy.done;
|
|
1342
|
+
}
|
|
1343
|
+
function installRevealHook() {
|
|
1344
|
+
const hy = globalThis._$HY;
|
|
1345
|
+
if (!hy || hy.$sc) return;
|
|
1346
|
+
hy.$sc = true;
|
|
1347
|
+
const prev = hy.fe;
|
|
1348
|
+
hy.fe = (fragmentId, parent) => {
|
|
1349
|
+
if (prev) prev(fragmentId, parent);
|
|
1350
|
+
if (!boundaryIndex) return;
|
|
1351
|
+
const root = parent || (typeof document !== "undefined" ? document.body : null);
|
|
1352
|
+
if (!root) return;
|
|
1353
|
+
indexBoundaries(root);
|
|
1354
|
+
for (const [id, notify] of boundaryWaiters) {
|
|
1355
|
+
const el = boundaryIndex.get(id);
|
|
1356
|
+
if (!el) continue;
|
|
1357
|
+
boundaryWaiters.delete(id);
|
|
1358
|
+
notify(el);
|
|
1359
|
+
}
|
|
1360
|
+
};
|
|
1361
|
+
}
|
|
1325
1362
|
function documentBoundary(host, id, props) {
|
|
1326
|
-
const
|
|
1327
|
-
|
|
1363
|
+
const claimed = claimedBoundaries.has(id);
|
|
1364
|
+
const el = !claimed ? findBoundaryElement(id) : undefined;
|
|
1365
|
+
if (el) return adoptBoundary(host, id, el, props);
|
|
1366
|
+
if (!claimed && !boundaryWaiters.has(id) && documentStreaming()) {
|
|
1367
|
+
const owner = getOwner();
|
|
1368
|
+
const arrival = new Promise(resolve => boundaryWaiters.set(id, resolve));
|
|
1369
|
+
onCleanup(() => boundaryWaiters.delete(id));
|
|
1370
|
+
return createMemo(() => arrival.then(node => runWithOwner(owner, () => adoptBoundary(host, id, node, props))));
|
|
1371
|
+
}
|
|
1372
|
+
return boundaryComponent(host, id)(props);
|
|
1373
|
+
}
|
|
1374
|
+
function adoptBoundary(host, id, el, props) {
|
|
1328
1375
|
claimedBoundaries.add(id);
|
|
1329
1376
|
const hy = globalThis._$HY;
|
|
1330
1377
|
if (hy && hy.r) {
|
|
@@ -1376,6 +1423,7 @@ function installServerComponents(host = getFrameHost()) {
|
|
|
1376
1423
|
};
|
|
1377
1424
|
}
|
|
1378
1425
|
g._$SC.impl = (id, props) => documentBoundary(host, id, props);
|
|
1426
|
+
installRevealHook();
|
|
1379
1427
|
configureServerFunctionsClient({
|
|
1380
1428
|
responseHandler: createServerComponentHandler({
|
|
1381
1429
|
host,
|
package/frames/dist/client.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getOwner,
|
|
1
|
+
import { getOwner, onCleanup, createMemo, runWithOwner, createLoadingBoundary, sharedConfig, createOwner } from 'solid-js';
|
|
2
2
|
import { insert } from '@solidjs/web';
|
|
3
3
|
import { configureServerFunctionsClient } from '@solidjs/web/server-functions/client';
|
|
4
4
|
import { fromCrossJSON, Feature } from 'seroval';
|
|
@@ -112,7 +112,7 @@ function createFrameHost(options = {}) {
|
|
|
112
112
|
pending.delete(id);
|
|
113
113
|
const records = {};
|
|
114
114
|
let version;
|
|
115
|
-
for (const chunk of buffered) {
|
|
115
|
+
for (const chunk of buffered.chunks) {
|
|
116
116
|
if (chunk.type === "data") {
|
|
117
117
|
options.applyData && options.applyData(chunk);
|
|
118
118
|
continue;
|
|
@@ -144,12 +144,20 @@ function createFrameHost(options = {}) {
|
|
|
144
144
|
for (const frame of set) deliver(frame, chunk);
|
|
145
145
|
return;
|
|
146
146
|
}
|
|
147
|
-
const buffered = pending.get(chunk.id)
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
147
|
+
const buffered = pending.get(chunk.id);
|
|
148
|
+
if (!buffered) {
|
|
149
|
+
pending.set(chunk.id, {
|
|
150
|
+
version: chunk.version,
|
|
151
|
+
chunks: [chunk]
|
|
152
|
+
});
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
if (chunk.version < buffered.version) return;
|
|
156
|
+
if (chunk.version > buffered.version) {
|
|
157
|
+
buffered.version = chunk.version;
|
|
158
|
+
buffered.chunks.length = 0;
|
|
159
|
+
}
|
|
160
|
+
buffered.chunks.push(chunk);
|
|
153
161
|
},
|
|
154
162
|
get(id) {
|
|
155
163
|
const set = frames.get(id);
|
|
@@ -208,7 +216,7 @@ class FrameImpl {
|
|
|
208
216
|
if (options.host && options.id !== undefined) {
|
|
209
217
|
options.host.register(options.id, this);
|
|
210
218
|
}
|
|
211
|
-
if (options.adopt) this.#syncSlots();
|
|
219
|
+
if (options.adopt && this.#version === undefined) this.#syncSlots();
|
|
212
220
|
}
|
|
213
221
|
#parent() {
|
|
214
222
|
return this.#element ?? this.#start.parentNode;
|
|
@@ -352,7 +360,7 @@ class FrameImpl {
|
|
|
352
360
|
if (nodes) this.#replaceRange(occurrence, start, nodes);
|
|
353
361
|
this.#slotNodes.set(occurrence, nodes);
|
|
354
362
|
this.#mountedSlots.add(occurrence);
|
|
355
|
-
this.#discoverRegions(occurrence, start);
|
|
363
|
+
if (!this.#options.adopt || nodes) this.#discoverRegions(occurrence, start);
|
|
356
364
|
this.#bindRegions(occurrence);
|
|
357
365
|
} else if (record !== this.#slotArgs.get(occurrence)) {
|
|
358
366
|
if (this.#refArgsUnchanged(occurrence, record)) {
|
|
@@ -1224,15 +1232,18 @@ function normalizeSlotContent(value) {
|
|
|
1224
1232
|
if (value == null || typeof value === "boolean") return document.createTextNode("");
|
|
1225
1233
|
return value instanceof Node ? value : document.createTextNode(String(value));
|
|
1226
1234
|
}
|
|
1235
|
+
function gatherClaims(el, registry) {
|
|
1236
|
+
if (el.hasAttribute("_hk")) registry.set(el.getAttribute("_hk"), el);
|
|
1237
|
+
if (el.hasAttribute(FRAME_ID_ATTR)) return;
|
|
1238
|
+
for (let c = el.firstElementChild; c; c = c.nextElementSibling) gatherClaims(c, registry);
|
|
1239
|
+
}
|
|
1227
1240
|
function claimRender(prefix, existing, render) {
|
|
1228
1241
|
const sc = sharedConfig;
|
|
1229
1242
|
if (!sc.getNextContextId) return render();
|
|
1230
1243
|
const registry = new Map();
|
|
1231
1244
|
for (const n of existing) {
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
if (el.hasAttribute("_hk")) registry.set(el.getAttribute("_hk"), el);
|
|
1235
|
-
el.querySelectorAll("*[_hk]").forEach(child => registry.set(child.getAttribute("_hk"), child));
|
|
1245
|
+
if (n.nodeType !== 1) continue;
|
|
1246
|
+
gatherClaims(n, registry);
|
|
1236
1247
|
}
|
|
1237
1248
|
if (!registry.size) return render();
|
|
1238
1249
|
const prevRegistry = sc.registry;
|
|
@@ -1296,21 +1307,57 @@ function boundaryComponent(host, id) {
|
|
|
1296
1307
|
}
|
|
1297
1308
|
const claimedBoundaries = new Set();
|
|
1298
1309
|
let boundaryIndex = null;
|
|
1310
|
+
const isBoundaryId = id => !id.includes(".");
|
|
1311
|
+
function indexBoundaries(root) {
|
|
1312
|
+
root.querySelectorAll(`[${FRAME_ID_ATTR}]`).forEach(el => {
|
|
1313
|
+
const key = el.getAttribute(FRAME_ID_ATTR);
|
|
1314
|
+
if (key && isBoundaryId(key) && !boundaryIndex.has(key)) boundaryIndex.set(key, el);
|
|
1315
|
+
});
|
|
1316
|
+
}
|
|
1299
1317
|
function findBoundaryElement(id) {
|
|
1300
1318
|
if (!boundaryIndex) {
|
|
1301
1319
|
boundaryIndex = new Map();
|
|
1302
|
-
if (typeof document !== "undefined" && document.body)
|
|
1303
|
-
document.body.querySelectorAll(`[${FRAME_ID_ATTR}]`).forEach(el => {
|
|
1304
|
-
const key = el.getAttribute(FRAME_ID_ATTR);
|
|
1305
|
-
if (key && !boundaryIndex.has(key)) boundaryIndex.set(key, el);
|
|
1306
|
-
});
|
|
1307
|
-
}
|
|
1320
|
+
if (typeof document !== "undefined" && document.body) indexBoundaries(document.body);
|
|
1308
1321
|
}
|
|
1309
1322
|
return boundaryIndex.get(id);
|
|
1310
1323
|
}
|
|
1324
|
+
const boundaryWaiters = new Map();
|
|
1325
|
+
function documentStreaming() {
|
|
1326
|
+
const hy = globalThis._$HY;
|
|
1327
|
+
return !!hy && !hy.done;
|
|
1328
|
+
}
|
|
1329
|
+
function installRevealHook() {
|
|
1330
|
+
const hy = globalThis._$HY;
|
|
1331
|
+
if (!hy || hy.$sc) return;
|
|
1332
|
+
hy.$sc = true;
|
|
1333
|
+
const prev = hy.fe;
|
|
1334
|
+
hy.fe = (fragmentId, parent) => {
|
|
1335
|
+
if (prev) prev(fragmentId, parent);
|
|
1336
|
+
if (!boundaryIndex) return;
|
|
1337
|
+
const root = parent || (typeof document !== "undefined" ? document.body : null);
|
|
1338
|
+
if (!root) return;
|
|
1339
|
+
indexBoundaries(root);
|
|
1340
|
+
for (const [id, notify] of boundaryWaiters) {
|
|
1341
|
+
const el = boundaryIndex.get(id);
|
|
1342
|
+
if (!el) continue;
|
|
1343
|
+
boundaryWaiters.delete(id);
|
|
1344
|
+
notify(el);
|
|
1345
|
+
}
|
|
1346
|
+
};
|
|
1347
|
+
}
|
|
1311
1348
|
function documentBoundary(host, id, props) {
|
|
1312
|
-
const
|
|
1313
|
-
|
|
1349
|
+
const claimed = claimedBoundaries.has(id);
|
|
1350
|
+
const el = !claimed ? findBoundaryElement(id) : undefined;
|
|
1351
|
+
if (el) return adoptBoundary(host, id, el, props);
|
|
1352
|
+
if (!claimed && !boundaryWaiters.has(id) && documentStreaming()) {
|
|
1353
|
+
const owner = getOwner();
|
|
1354
|
+
const arrival = new Promise(resolve => boundaryWaiters.set(id, resolve));
|
|
1355
|
+
onCleanup(() => boundaryWaiters.delete(id));
|
|
1356
|
+
return createMemo(() => arrival.then(node => runWithOwner(owner, () => adoptBoundary(host, id, node, props))));
|
|
1357
|
+
}
|
|
1358
|
+
return boundaryComponent(host, id)(props);
|
|
1359
|
+
}
|
|
1360
|
+
function adoptBoundary(host, id, el, props) {
|
|
1314
1361
|
claimedBoundaries.add(id);
|
|
1315
1362
|
const hy = globalThis._$HY;
|
|
1316
1363
|
if (hy && hy.r) {
|
|
@@ -1362,6 +1409,7 @@ function installServerComponents(host = getFrameHost()) {
|
|
|
1362
1409
|
};
|
|
1363
1410
|
}
|
|
1364
1411
|
g._$SC.impl = (id, props) => documentBoundary(host, id, props);
|
|
1412
|
+
installRevealHook();
|
|
1365
1413
|
configureServerFunctionsClient({
|
|
1366
1414
|
responseHandler: createServerComponentHandler({
|
|
1367
1415
|
host,
|