@solidjs/web 2.0.0-beta.25 → 2.0.0-beta.26

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.
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var solidJs = require('solid-js');
4
+ var web$1 = require('@solidjs/web');
4
5
  var client = require('@solidjs/web/server-functions/client');
5
6
  var seroval = require('seroval');
6
7
  var web = require('seroval-plugins/web');
@@ -66,22 +67,6 @@ function chunkToRecords(chunk) {
66
67
  args: chunk.args
67
68
  }
68
69
  };
69
- case "template":
70
- return {
71
- [`tpl:${chunk.key}`]: {
72
- kind: "template",
73
- html: chunk.html,
74
- fields: chunk.fields
75
- }
76
- };
77
- case "block":
78
- return {
79
- [`seg:${chunk.key}`]: {
80
- kind: "block",
81
- template: `tpl:${chunk.template}`,
82
- values: chunk.values
83
- }
84
- };
85
70
  case "complete":
86
71
  return {
87
72
  ":complete": true
@@ -275,7 +260,7 @@ class FrameImpl {
275
260
  this.#revealed.clear();
276
261
  this.#fallbackShown.clear();
277
262
  for (const key of Object.keys(this.#store)) {
278
- if (key.startsWith("seg:") || key.startsWith("tpl:") || key === ":error") {
263
+ if (key.startsWith("seg:") || key === ":error") {
279
264
  delete this.#store[key];
280
265
  }
281
266
  }
@@ -344,10 +329,14 @@ class FrameImpl {
344
329
  if (record !== undefined) return record;
345
330
  return this.#options.resolveSlotRecord?.(occurrence);
346
331
  }
347
- #syncSlots() {
332
+ #removeSlotRecord(occurrence) {
333
+ const key = `slot:${occurrence}`;
334
+ if (key in this.#store) delete this.#store[key];else this.#options.removeSlotRecord?.(occurrence);
335
+ }
336
+ #syncSlots(root) {
348
337
  if (!this.#slots && !this.#options.resolveSlot) return;
349
338
  const found = new Map();
350
- this.#collectSlots(found);
339
+ if (root) collectSlots(root, found);else this.#collectSlots(found);
351
340
  for (const [occurrence, start] of found) {
352
341
  const callback = this.#resolveSlot(propOf(occurrence));
353
342
  if (!callback) continue;
@@ -360,6 +349,7 @@ class FrameImpl {
360
349
  this.#runSlotCleanups(occurrence);
361
350
  }
362
351
  if (!this.#mountedSlots.has(occurrence)) {
352
+ if (this.#options.adopt) this.#discoverRegions(occurrence, start);
363
353
  const nodes = this.#invokeSlot(occurrence, callback, record, start, this.#options.adopt);
364
354
  if (nodes) this.#replaceRange(occurrence, start, nodes);
365
355
  this.#slotNodes.set(occurrence, nodes);
@@ -377,8 +367,10 @@ class FrameImpl {
377
367
  this.#bindRegions(occurrence);
378
368
  }
379
369
  }
380
- for (const occurrence of [...this.#mountedSlots]) {
381
- if (!found.has(occurrence)) this.#unmountSlot(occurrence);
370
+ if (!root) {
371
+ for (const occurrence of [...this.#mountedSlots]) {
372
+ if (!found.has(occurrence)) this.#unmountSlot(occurrence);
373
+ }
382
374
  }
383
375
  }
384
376
  #invokeSlot(occurrence, callback, record, start, adopted) {
@@ -391,6 +383,13 @@ class FrameImpl {
391
383
  existing: start ? rangeInterior(start, slotEnd(occurrence)) : []
392
384
  };
393
385
  const props = record && record.kind === "slot" ? this.#resolveArgs(occurrence, record.args) : {};
386
+ const regions = this.#slotRegions.get(occurrence);
387
+ if (regions) {
388
+ for (const entry of regions.values()) {
389
+ const argKey = entry.childId.slice(entry.childId.lastIndexOf(".") + 1);
390
+ if (!(argKey in props)) props[argKey] = entry.element;
391
+ }
392
+ }
394
393
  const content = callback(props, ctx);
395
394
  this.#slotArgs.set(occurrence, record);
396
395
  if (cleanups.length) this.#slotCleanups.set(occurrence, cleanups);
@@ -413,7 +412,7 @@ class FrameImpl {
413
412
  this.#slotNodes.delete(key);
414
413
  this.#slotArgs.delete(key);
415
414
  this.#slotResolvedRefs.delete(key);
416
- delete this.#store[`slot:${key}`];
415
+ this.#removeSlotRecord(key);
417
416
  this.#runSlotCleanups(key);
418
417
  const regions = this.#slotRegions.get(key);
419
418
  if (regions) {
@@ -447,29 +446,17 @@ class FrameImpl {
447
446
  cache[key] = resolved;
448
447
  props[key] = resolved;
449
448
  } else if (isFrameRef(value)) {
450
- const fragment = document.createDocumentFragment();
451
449
  let entry = regions.get(value.$frame);
452
450
  if (!entry) {
453
- const start = document.createComment(`frame:${value.$frame}:start`);
454
- const end = document.createComment(`frame:${value.$frame}:end`);
451
+ const element = makeFrameElement(value.$frame);
455
452
  entry = {
456
453
  childId: value.$frame,
457
- start,
458
- end,
454
+ element,
459
455
  frame: undefined
460
456
  };
461
457
  regions.set(value.$frame, entry);
462
- fragment.append(start, end);
463
- } else {
464
- let n = entry.start;
465
- while (n) {
466
- const next = n.nextSibling;
467
- fragment.append(n);
468
- if (n === entry.end) break;
469
- n = next;
470
- }
471
458
  }
472
- props[key] = fragment;
459
+ props[key] = entry.element;
473
460
  } else {
474
461
  props[key] = value;
475
462
  }
@@ -483,49 +470,12 @@ class FrameImpl {
483
470
  regions = new Map();
484
471
  this.#slotRegions.set(slotKey, regions);
485
472
  }
486
- const doc = start.ownerDocument;
487
473
  const endData = slotEnd(slotKey);
488
- const comments = [];
489
474
  let n = start.nextSibling;
490
475
  while (n && !(n.nodeType === COMMENT_NODE && n.data === endData)) {
491
- if (n.nodeType === COMMENT_NODE) comments.push(n);else if (n.nodeType === 1) {
492
- const walker = doc.createTreeWalker(n, 128 );
493
- let c;
494
- while (c = walker.nextNode()) comments.push(c);
495
- }
476
+ collectRegionElements(n, regions);
496
477
  n = n.nextSibling;
497
478
  }
498
- let depth = 0;
499
- let openId = null;
500
- let openStart = null;
501
- for (const c of comments) {
502
- const data = c.data;
503
- if (!data.startsWith("frame:")) continue;
504
- if (data.endsWith(":start")) {
505
- const childId = data.slice(6, -6);
506
- if (!childId) continue;
507
- if (depth === 0) {
508
- openId = childId;
509
- openStart = c;
510
- }
511
- depth++;
512
- } else if (data.endsWith(":end")) {
513
- const childId = data.slice(6, -4);
514
- if (!childId) continue;
515
- if (depth > 0) {
516
- depth--;
517
- if (depth === 0 && childId === openId && !regions.has(openId)) {
518
- regions.set(openId, {
519
- childId: openId,
520
- start: openStart,
521
- end: c,
522
- frame: undefined,
523
- adopt: true
524
- });
525
- }
526
- }
527
- }
528
- }
529
479
  }
530
480
  #refArgsUnchanged(occurrence, record) {
531
481
  const old = this.#slotArgs.get(occurrence);
@@ -569,15 +519,16 @@ class FrameImpl {
569
519
  const regions = this.#slotRegions.get(slotKey);
570
520
  if (!regions) return;
571
521
  for (const entry of regions.values()) {
572
- if (!entry.frame && entry.start.parentNode) {
573
- entry.frame = new FrameImpl(null, entry.start, entry.end, {
522
+ if (!entry.frame) {
523
+ entry.frame = new FrameImpl(entry.element, null, null, {
574
524
  id: entry.childId,
575
525
  host: this.#options.host,
576
526
  adopt: entry.adopt,
577
527
  claimScope: this.#options.claimScope ?? this.#options.id,
578
528
  ownerScope: this.#options.ownerScope,
579
529
  resolveSlot: prop => this.#resolveSlot(prop),
580
- resolveSlotRecord: occurrence => this.#resolveSlotRecord(occurrence)
530
+ resolveSlotRecord: occurrence => this.#resolveSlotRecord(occurrence),
531
+ removeSlotRecord: occurrence => this.#removeSlotRecord(occurrence)
581
532
  });
582
533
  }
583
534
  }
@@ -592,12 +543,7 @@ class FrameImpl {
592
543
  n = afterRange(n, id);
593
544
  continue;
594
545
  }
595
- const regionId = frameRegionStartId(n);
596
- if (regionId !== null) {
597
- n = afterFrameRegion(n, regionId);
598
- continue;
599
- }
600
- if (n.nodeType === ELEMENT_NODE) collectSlots(n, found);
546
+ if (n.nodeType === ELEMENT_NODE && !isFrameElement(n)) collectSlots(n, found);
601
547
  n = n.nextSibling;
602
548
  }
603
549
  }
@@ -619,6 +565,7 @@ class FrameImpl {
619
565
  if (this.#disposed) return;
620
566
  this.#disposed = true;
621
567
  for (const key of [...this.#slotCleanups.keys()]) this.#runSlotCleanups(key);
568
+ for (const key of this.#mountedSlots) this.#removeSlotRecord(key);
622
569
  for (const regions of this.#slotRegions.values()) {
623
570
  for (const {
624
571
  frame
@@ -664,13 +611,7 @@ class FrameImpl {
664
611
  }
665
612
  #segmentReady(name) {
666
613
  const content = this.#store[`seg:${name}`];
667
- if (!content) return false;
668
- if (content.kind === "block") {
669
- const template = this.#store[content.template];
670
- if (!template || template.kind !== "template") return false;
671
- } else if (content.kind !== "html") {
672
- return false;
673
- }
614
+ if (!content || content.kind !== "html") return false;
674
615
  if (!this.#store[`seg:${name}:reveal`]) return false;
675
616
  const assets = this.#store[`seg:${name}:assets`];
676
617
  if (assets && assets.styles) {
@@ -697,6 +638,23 @@ class FrameImpl {
697
638
  parent.removeChild(n);
698
639
  n = next;
699
640
  }
641
+ if (this.#options.reveal) {
642
+ const fallbackFrag = tpl.content.cloneNode(true);
643
+ this.#claimTree(fallbackFrag);
644
+ this.#options.reveal({
645
+ before: closing,
646
+ fallback: [...fallbackFrag.childNodes],
647
+ content: () => {
648
+ const materialized = this.#materialize(content);
649
+ this.#syncSlots(materialized);
650
+ this.#claimTree(materialized);
651
+ return materialized;
652
+ }
653
+ });
654
+ tpl.remove();
655
+ this.#revealed.add(name);
656
+ return;
657
+ }
700
658
  const materialized = this.#materialize(content);
701
659
  this.#claimTree(materialized);
702
660
  parent.insertBefore(materialized, closing);
@@ -715,70 +673,37 @@ class FrameImpl {
715
673
  return true;
716
674
  }
717
675
  #materialize(record) {
718
- if (record.kind === "html") return parseFragment(record.value);
719
- if (record.kind === "block") {
720
- const template = this.#store[record.template];
721
- if (!template || template.kind !== "template") return parseFragment("");
722
- return materializeBlock(template, record.values);
723
- }
724
- return parseFragment("");
676
+ return record.kind === "html" ? parseFragment(record.value) : parseFragment("");
725
677
  }
726
678
  }
727
- function materializeBlock(template, values) {
728
- const fragment = parseFragment(template.html);
729
- for (let i = 0; i < template.fields.length; i++) {
730
- const marker = `field:${template.fields[i]}`;
731
- const value = values[i] == null ? "" : String(values[i]);
732
- let hole = findComment(fragment, marker);
733
- while (hole) {
734
- hole.replaceWith(document.createTextNode(value));
735
- hole = findComment(fragment, marker);
736
- }
737
- }
738
- return fragment;
739
- }
740
679
  function createFrame(boundary, options) {
741
680
  return new FrameImpl(boundary, null, null, options);
742
681
  }
743
- function adoptFrameRange(start, end, options) {
744
- return new FrameImpl(null, start, end, {
745
- ...options,
746
- adopt: true
747
- });
748
- }
749
- const FRAME = Symbol.for("dom-expressions.frame");
750
- function createFrameInsertable(options) {
751
- let frame = null;
752
- let start = null;
753
- let end = null;
682
+ const FRAME_TAG = "dx-frame";
683
+ const FRAME_ID_ATTR = "data-fid";
684
+ function createFrameElement(options) {
685
+ const el = makeFrameElement(options.id);
686
+ const frame = new FrameImpl(el, null, null, options);
754
687
  return {
688
+ element: el,
755
689
  get frame() {
756
690
  return frame;
757
691
  },
758
692
  dispose() {
759
- if (!frame) return;
760
693
  frame.dispose();
761
- frame = null;
762
- const parent = start.parentNode;
763
- if (!parent) return;
764
- let n = start;
765
- while (n) {
766
- const next = n.nextSibling;
767
- parent.removeChild(n);
768
- if (n === end) break;
769
- n = next;
770
- }
771
- },
772
- [FRAME](parent, marker) {
773
- if (frame) return;
774
- start = document.createComment("frame:start");
775
- end = document.createComment("frame:end");
776
- parent.insertBefore(start, marker);
777
- parent.insertBefore(end, marker);
778
- frame = new FrameImpl(null, start, end, options);
694
+ el.remove();
779
695
  }
780
696
  };
781
697
  }
698
+ function makeFrameElement(id) {
699
+ const el = document.createElement(FRAME_TAG);
700
+ el.style.display = "contents";
701
+ if (id !== undefined) el.setAttribute(FRAME_ID_ATTR, id);
702
+ return el;
703
+ }
704
+ function isFrameElement(node) {
705
+ return node.nodeType === ELEMENT_NODE && node.hasAttribute(FRAME_ID_ATTR);
706
+ }
782
707
  function segmentName(key) {
783
708
  const m = /^seg:([^:]+)$/.exec(key);
784
709
  return m ? m[1] : null;
@@ -877,29 +802,25 @@ function collectSlots(root, out) {
877
802
  n = afterRange(n, id);
878
803
  continue;
879
804
  }
880
- const regionId = frameRegionStartId(n);
881
- if (regionId !== null) {
882
- n = afterFrameRegion(n, regionId);
883
- continue;
884
- }
885
- if (n.nodeType === ELEMENT_NODE) collectSlots(n, out);
805
+ if (n.nodeType === ELEMENT_NODE && !isFrameElement(n)) collectSlots(n, out);
886
806
  n = n.nextSibling;
887
807
  }
888
808
  }
889
- const FRAME_REGION_START = /^frame:(.+):start$/;
890
- function frameRegionStartId(node) {
891
- if (node.nodeType !== COMMENT_NODE) return null;
892
- const m = FRAME_REGION_START.exec(node.data);
893
- return m ? m[1] : null;
894
- }
895
- function afterFrameRegion(start, id) {
896
- const end = `frame:${id}:end`;
897
- let n = start.nextSibling;
898
- while (n) {
899
- if (n.nodeType === COMMENT_NODE && n.data === end) return n.nextSibling;
900
- n = n.nextSibling;
809
+ function collectRegionElements(node, regions) {
810
+ if (node.nodeType !== ELEMENT_NODE) return;
811
+ if (isFrameElement(node)) {
812
+ const childId = node.getAttribute(FRAME_ID_ATTR);
813
+ if (childId && !regions.has(childId)) {
814
+ regions.set(childId, {
815
+ childId,
816
+ element: node,
817
+ frame: undefined,
818
+ adopt: true
819
+ });
820
+ }
821
+ return;
901
822
  }
902
- return null;
823
+ for (let c = node.firstChild; c; c = c.nextSibling) collectRegionElements(c, regions);
903
824
  }
904
825
  function argsEquivalent(a, b) {
905
826
  if (a === b) return true;
@@ -927,18 +848,6 @@ function rangeInterior(start, endData) {
927
848
  }
928
849
  return nodes;
929
850
  }
930
- function findComment(root, data) {
931
- const children = root.childNodes;
932
- for (let i = 0; i < children.length; i++) {
933
- const node = children[i];
934
- if (node.nodeType === COMMENT_NODE && node.data === data) return node;
935
- if (node.nodeType === ELEMENT_NODE) {
936
- const found = findComment(node, data);
937
- if (found) return found;
938
- }
939
- }
940
- return null;
941
- }
942
851
  function slotStartId(node) {
943
852
  if (node.nodeType !== COMMENT_NODE) return null;
944
853
  const m = SLOT_START.exec(node.data);
@@ -954,12 +863,18 @@ function compatible(a, b) {
954
863
  if (a.nodeType === ELEMENT_NODE) return a.nodeName === b.nodeName;
955
864
  return a.nodeType === TEXT_NODE || a.nodeType === COMMENT_NODE;
956
865
  }
866
+ function preservesOpen(el) {
867
+ const t = el.tagName;
868
+ return t === "DETAILS" || t === "DIALOG";
869
+ }
957
870
  function morphAttributes(oldEl, newEl, claim) {
958
871
  let reclaim = false;
959
872
  let changed = false;
873
+ const keepOpen = preservesOpen(oldEl);
960
874
  const oldAttrs = oldEl.attributes;
961
875
  for (let i = oldAttrs.length - 1; i >= 0; i--) {
962
876
  const name = oldAttrs[i].name;
877
+ if (keepOpen && name === "open") continue;
963
878
  if (!newEl.hasAttribute(name)) {
964
879
  oldEl.removeAttribute(name);
965
880
  changed = true;
@@ -969,6 +884,7 @@ function morphAttributes(oldEl, newEl, claim) {
969
884
  const newAttrs = newEl.attributes;
970
885
  for (let i = 0; i < newAttrs.length; i++) {
971
886
  const attr = newAttrs[i];
887
+ if (keepOpen && attr.name === "open") continue;
972
888
  if (oldEl.getAttribute(attr.name) !== attr.value) {
973
889
  oldEl.setAttribute(attr.name, attr.value);
974
890
  changed = true;
@@ -979,6 +895,7 @@ function morphAttributes(oldEl, newEl, claim) {
979
895
  }
980
896
  function morphNode(oldNode, newNode, claim) {
981
897
  if (oldNode.nodeType === ELEMENT_NODE) {
898
+ if (oldNode.hasAttribute("data-preserve")) return;
982
899
  morphAttributes(oldNode, newNode, claim);
983
900
  reconcileChildren(oldNode, newNode, null, null, claim);
984
901
  } else if (oldNode.data !== newNode.data) {
@@ -1163,15 +1080,15 @@ class ChunkReader {
1163
1080
  }
1164
1081
  }
1165
1082
  async next() {
1166
- if (this.buffer.length === 0) {
1083
+ while (this.buffer.length < 12) {
1167
1084
  if (this.done) {
1168
- return {
1085
+ if (this.buffer.length === 0) return {
1169
1086
  done: true,
1170
1087
  value: undefined
1171
1088
  };
1089
+ throw new Error("Malformed server function stream.");
1172
1090
  }
1173
1091
  await this.readChunk();
1174
- return await this.next();
1175
1092
  }
1176
1093
  const head = new TextDecoder().decode(this.buffer.subarray(1, 11));
1177
1094
  const bytes = Number.parseInt(head, 16);
@@ -1359,50 +1276,44 @@ function slotsFor(props) {
1359
1276
  }
1360
1277
  });
1361
1278
  }
1279
+ function revealSeam(owner) {
1280
+ return seam => solidJs.runWithOwner(owner, () => web$1.insert(seam.before.parentNode, solidJs.createLoadingBoundary(() => seam.content(), () => seam.fallback), seam.before));
1281
+ }
1362
1282
  function boundaryComponent(host, id) {
1363
1283
  return props => {
1364
1284
  const owner = solidJs.getOwner();
1365
- const insertable = createFrameInsertable({
1285
+ const {
1286
+ element,
1287
+ dispose
1288
+ } = createFrameElement({
1366
1289
  host,
1367
1290
  id,
1368
1291
  slots: slotsFor(props),
1369
- ownerScope: fn => solidJs.runWithOwner(owner, fn)
1292
+ ownerScope: fn => solidJs.runWithOwner(owner, fn),
1293
+ reveal: revealSeam(owner)
1370
1294
  });
1371
- solidJs.onCleanup(() => insertable.dispose());
1372
- return insertable;
1295
+ solidJs.onCleanup(dispose);
1296
+ return element;
1373
1297
  };
1374
1298
  }
1375
1299
  const claimedBoundaries = new Set();
1376
1300
  let boundaryIndex = null;
1377
- function findBoundaryRange(id) {
1301
+ function findBoundaryElement(id) {
1378
1302
  if (!boundaryIndex) {
1379
1303
  boundaryIndex = new Map();
1380
1304
  if (typeof document !== "undefined" && document.body) {
1381
- const walker = document.createTreeWalker(document.body, 128 );
1382
- const opens = {};
1383
- let c;
1384
- while (c = walker.nextNode()) {
1385
- const d = c.data;
1386
- if (!d.startsWith("frame:")) continue;
1387
- if (d.endsWith(":start")) {
1388
- const key = d.slice(6, -6);
1389
- if (key && !(key in opens)) opens[key] = c;
1390
- } else if (d.endsWith(":end")) {
1391
- const key = d.slice(6, -4);
1392
- if (key && opens[key] && !boundaryIndex.has(key)) {
1393
- boundaryIndex.set(key, [opens[key], c]);
1394
- }
1395
- }
1396
- }
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
+ });
1397
1309
  }
1398
1310
  }
1399
1311
  return boundaryIndex.get(id);
1400
1312
  }
1401
1313
  function documentBoundary(host, id, props) {
1402
- const range = !claimedBoundaries.has(id) && findBoundaryRange(id);
1403
- if (!range) return boundaryComponent(host, id)(props);
1314
+ const el = !claimedBoundaries.has(id) ? findBoundaryElement(id) : undefined;
1315
+ if (!el) return boundaryComponent(host, id)(props);
1404
1316
  claimedBoundaries.add(id);
1405
- const [start, end] = range;
1406
1317
  const hy = globalThis._$HY;
1407
1318
  if (hy && hy.r) {
1408
1319
  const slotPrefix = `sc:slot:${id}:`;
@@ -1431,19 +1342,16 @@ function documentBoundary(host, id, props) {
1431
1342
  }
1432
1343
  }
1433
1344
  const owner = solidJs.getOwner();
1434
- const frame = adoptFrameRange(start, end, {
1345
+ const frame = createFrame(el, {
1346
+ adopt: true,
1435
1347
  host,
1436
1348
  id,
1437
1349
  slots: slotsFor(props),
1438
- ownerScope: fn => solidJs.runWithOwner(owner, fn)
1350
+ ownerScope: fn => solidJs.runWithOwner(owner, fn),
1351
+ reveal: revealSeam(owner)
1439
1352
  });
1440
1353
  solidJs.onCleanup(() => frame.dispose());
1441
- const nodes = [];
1442
- for (let n = start; n; n = n.nextSibling) {
1443
- nodes.push(n);
1444
- if (n === end) break;
1445
- }
1446
- return nodes;
1354
+ return el;
1447
1355
  }
1448
1356
  function installServerComponents(host = getFrameHost()) {
1449
1357
  const g = globalThis;
@@ -1466,7 +1374,7 @@ function installServerComponents(host = getFrameHost()) {
1466
1374
  intercept: ({
1467
1375
  id
1468
1376
  }) => {
1469
- if (claimedBoundaries.has(id) || !findBoundaryRange(id)) return undefined;
1377
+ if (claimedBoundaries.has(id) || !findBoundaryElement(id)) return undefined;
1470
1378
  return g._$SC.r(id);
1471
1379
  }
1472
1380
  })
@@ -1477,8 +1385,8 @@ exports.FRAME_APPLIED_EVENT = FRAME_APPLIED_EVENT;
1477
1385
  exports.FRAME_STREAM_HEADER = FRAME_STREAM_HEADER;
1478
1386
  exports.applyFrameResponse = applyFrameResponse;
1479
1387
  exports.createFrame = createFrame;
1388
+ exports.createFrameElement = createFrameElement;
1480
1389
  exports.createFrameHost = createFrameHost;
1481
- exports.createFrameInsertable = createFrameInsertable;
1482
1390
  exports.createJSONDataTable = createJSONDataTable;
1483
1391
  exports.createServerComponentHandler = createServerComponentHandler;
1484
1392
  exports.getFrameHost = getFrameHost;