@manyducks.co/dolla 0.72.0 → 0.74.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/lib/index.js CHANGED
@@ -708,11 +708,11 @@ var Conditional = class {
708
708
  get connected() {
709
709
  return this.node.parentNode != null;
710
710
  }
711
- connect(parent, after) {
711
+ connect(parent2, after) {
712
712
  if (!this.connected) {
713
- parent.insertBefore(this.node, after?.nextSibling ?? null);
713
+ parent2.insertBefore(this.node, after?.nextSibling ?? null);
714
714
  if (this.appContext.mode === "development") {
715
- parent.insertBefore(this.endNode, this.node.nextSibling);
715
+ parent2.insertBefore(this.endNode, this.node.nextSibling);
716
716
  }
717
717
  this.stopCallback = observe(this.$predicate, (value) => {
718
718
  this.update(value);
@@ -738,6 +738,9 @@ var Conditional = class {
738
738
  handle.disconnect();
739
739
  }
740
740
  this.connectedContent = [];
741
+ if (this.node.parentNode == null) {
742
+ return;
743
+ }
741
744
  if (value && this.thenContent) {
742
745
  this.connectedContent = renderMarkupToDOM(this.thenContent, this);
743
746
  } else if (!value && this.elseContent) {
@@ -816,9 +819,9 @@ var HTML = class {
816
819
  this.appContext = appContext;
817
820
  this.elementContext = elementContext;
818
821
  }
819
- connect(parent, after) {
820
- if (parent == null) {
821
- throw new Error(`HTML element requires a parent element as the first argument to connect. Got: ${parent}`);
822
+ connect(parent2, after) {
823
+ if (parent2 == null) {
824
+ throw new Error(`HTML element requires a parent element as the first argument to connect. Got: ${parent2}`);
822
825
  }
823
826
  if (!this.connected) {
824
827
  for (const child of this.children) {
@@ -830,7 +833,7 @@ var HTML = class {
830
833
  if (this.props.class)
831
834
  this.applyClasses(this.node, this.props.class, this.stopCallbacks);
832
835
  }
833
- parent.insertBefore(this.node, after?.nextSibling ?? null);
836
+ parent2.insertBefore(this.node, after?.nextSibling ?? null);
834
837
  setTimeout(() => {
835
838
  this.canClickAway = true;
836
839
  }, 0);
@@ -1237,9 +1240,9 @@ var Observer = class {
1237
1240
  }
1238
1241
  };
1239
1242
  }
1240
- connect(parent, after) {
1243
+ connect(parent2, after) {
1241
1244
  if (!this.connected) {
1242
- parent.insertBefore(this.node, after?.nextSibling ?? null);
1245
+ parent2.insertBefore(this.node, after?.nextSibling ?? null);
1243
1246
  this.observerControls.start();
1244
1247
  }
1245
1248
  }
@@ -1310,9 +1313,9 @@ var Outlet = class {
1310
1313
  get connected() {
1311
1314
  return this.node?.parentNode != null;
1312
1315
  }
1313
- connect(parent, after) {
1316
+ connect(parent2, after) {
1314
1317
  if (!this.connected) {
1315
- parent.insertBefore(this.node, after?.nextSibling ?? null);
1318
+ parent2.insertBefore(this.node, after?.nextSibling ?? null);
1316
1319
  this.stopCallback = observe(this.$children, (children) => {
1317
1320
  this.update(children);
1318
1321
  });
@@ -1335,12 +1338,12 @@ var Outlet = class {
1335
1338
  for (const child of this.connectedChildren) {
1336
1339
  child.disconnect();
1337
1340
  }
1338
- this.connectedChildren = newChildren;
1339
- for (let i = 0; i < this.connectedChildren.length; i++) {
1340
- const child = this.connectedChildren[i];
1341
- const previous = i > 0 ? this.connectedChildren[i] : void 0;
1341
+ for (let i = 0; i < newChildren.length; i++) {
1342
+ const child = newChildren[i];
1343
+ const previous = i > 0 ? newChildren[i] : void 0;
1342
1344
  child.connect(this.node.parentElement, previous?.node);
1343
1345
  }
1346
+ this.connectedChildren = newChildren;
1344
1347
  if (this.appContext.mode === "development") {
1345
1348
  this.node.textContent = `Outlet (${newChildren.length} ${newChildren.length === 1 ? "child" : "children"})`;
1346
1349
  this.node.parentElement?.insertBefore(
@@ -1350,6 +1353,7 @@ var Outlet = class {
1350
1353
  }
1351
1354
  }
1352
1355
  setChildren(children) {
1356
+ throw new Error(`setChildren is not supported on Outlet`);
1353
1357
  }
1354
1358
  };
1355
1359
 
@@ -1367,7 +1371,7 @@ var Portal = class {
1367
1371
  this.config = config;
1368
1372
  }
1369
1373
  connect(_parent, _after) {
1370
- const { content, parent } = this.config;
1374
+ const { content, parent: parent2 } = this.config;
1371
1375
  if (isDOMHandle(content)) {
1372
1376
  this.handle = content;
1373
1377
  } else if (isMarkup(content)) {
@@ -1375,7 +1379,7 @@ var Portal = class {
1375
1379
  } else {
1376
1380
  this.handle = getRenderHandle(renderMarkupToDOM(toMarkup(content), this.config));
1377
1381
  }
1378
- this.handle.connect(parent);
1382
+ this.handle.connect(parent2);
1379
1383
  }
1380
1384
  disconnect() {
1381
1385
  if (this.handle?.connected) {
@@ -1531,7 +1535,7 @@ function initView(config) {
1531
1535
  get connected() {
1532
1536
  return isConnected;
1533
1537
  },
1534
- connect(parent, after) {
1538
+ connect(parent2, after) {
1535
1539
  const wasConnected = isConnected;
1536
1540
  if (!wasConnected) {
1537
1541
  initialize();
@@ -1541,7 +1545,7 @@ function initView(config) {
1541
1545
  }
1542
1546
  }
1543
1547
  if (rendered) {
1544
- rendered.connect(parent, after);
1548
+ rendered.connect(parent2, after);
1545
1549
  }
1546
1550
  if (!wasConnected) {
1547
1551
  isConnected = true;
@@ -1572,6 +1576,7 @@ function initView(config) {
1572
1576
  }
1573
1577
  },
1574
1578
  async setChildren(children) {
1579
+ console.log("setChildren", { name: ctx.name, children });
1575
1580
  $$children.set(children);
1576
1581
  }
1577
1582
  };
@@ -1606,9 +1611,9 @@ var Repeat = class {
1606
1611
  this.endNode = document.createTextNode("");
1607
1612
  }
1608
1613
  }
1609
- connect(parent, after) {
1614
+ connect(parent2, after) {
1610
1615
  if (!this.connected) {
1611
- parent.insertBefore(this.node, after?.nextSibling ?? null);
1616
+ parent2.insertBefore(this.node, after?.nextSibling ?? null);
1612
1617
  this.stopCallback = observe(this.$items, (value) => {
1613
1618
  this._update(Array.from(value));
1614
1619
  });
@@ -1704,7 +1709,7 @@ var Text = class {
1704
1709
  constructor({ value }) {
1705
1710
  this.value = value;
1706
1711
  }
1707
- async connect(parent, after = null) {
1712
+ async connect(parent2, after = null) {
1708
1713
  if (!this.connected) {
1709
1714
  if (isReadable(this.value)) {
1710
1715
  this.stopCallback = observe(this.value, (value) => {
@@ -1714,7 +1719,7 @@ var Text = class {
1714
1719
  this.update(this.value);
1715
1720
  }
1716
1721
  }
1717
- parent.insertBefore(this.node, after?.nextSibling ?? null);
1722
+ parent2.insertBefore(this.node, after?.nextSibling ?? null);
1718
1723
  }
1719
1724
  async disconnect() {
1720
1725
  if (this.connected) {
@@ -1788,8 +1793,8 @@ function repeat(items, keyFn, renderFn) {
1788
1793
  const $items = $(items);
1789
1794
  return m("$repeat", { $items, keyFn, renderFn });
1790
1795
  }
1791
- function portal(content, parent) {
1792
- return m("$portal", { content, parent });
1796
+ function portal(content, parent2) {
1797
+ return m("$portal", { content, parent: parent2 });
1793
1798
  }
1794
1799
  var NodeHandle = class {
1795
1800
  node;
@@ -1799,8 +1804,8 @@ var NodeHandle = class {
1799
1804
  constructor(node) {
1800
1805
  this.node = node;
1801
1806
  }
1802
- async connect(parent, after) {
1803
- parent.insertBefore(this.node, after?.nextSibling ?? null);
1807
+ async connect(parent2, after) {
1808
+ parent2.insertBefore(this.node, after?.nextSibling ?? null);
1804
1809
  }
1805
1810
  async disconnect() {
1806
1811
  if (this.node.parentNode) {
@@ -1909,15 +1914,15 @@ function getRenderHandle(handles) {
1909
1914
  get connected() {
1910
1915
  return isConnected;
1911
1916
  },
1912
- async connect(parent, after) {
1913
- parent.insertBefore(node, after ? after : null);
1917
+ connect(parent2, after) {
1918
+ parent2.insertBefore(node, after ? after : null);
1914
1919
  for (const handle of handles) {
1915
1920
  const previous = handles[handles.length - 1]?.node ?? node;
1916
- await handle.connect(parent, previous);
1921
+ handle.connect(parent2, previous);
1917
1922
  }
1918
1923
  isConnected = true;
1919
1924
  },
1920
- async disconnect() {
1925
+ disconnect() {
1921
1926
  if (isConnected) {
1922
1927
  for (const handle of handles) {
1923
1928
  handle.disconnect();
@@ -1926,7 +1931,8 @@ function getRenderHandle(handles) {
1926
1931
  }
1927
1932
  isConnected = false;
1928
1933
  },
1929
- async setChildren() {
1934
+ setChildren() {
1935
+ throw new Error(`setChildren not supported on renderHandle`);
1930
1936
  }
1931
1937
  };
1932
1938
  }
@@ -3144,7 +3150,7 @@ function RouterStore(ctx) {
3144
3150
  history = createBrowserHistory();
3145
3151
  }
3146
3152
  let layerId = 0;
3147
- function prepareRoute(route, layers = []) {
3153
+ function prepareRoute(route, parents = [], layers = []) {
3148
3154
  if (!(typeof route === "object" && !Array.isArray(route)) || !(typeof route.path === "string")) {
3149
3155
  throw new TypeError(`Route configs must be objects with a 'path' string property. Got: ${route}`);
3150
3156
  }
@@ -3155,7 +3161,11 @@ function RouterStore(ctx) {
3155
3161
  } else if (!route.view && !route.routes && !route.redirect) {
3156
3162
  throw new Error(`Route must have a 'view', a 'redirect', or a set of nested 'routes'.`);
3157
3163
  }
3158
- const parts = splitPath(route.path);
3164
+ let parts = [];
3165
+ for (const parent2 of parents) {
3166
+ parts.push(...splitPath(parent2.path));
3167
+ }
3168
+ parts.push(...splitPath(route.path));
3159
3169
  if (parts[parts.length - 1] === "*") {
3160
3170
  parts.pop();
3161
3171
  }
@@ -3169,7 +3179,7 @@ function RouterStore(ctx) {
3169
3179
  }
3170
3180
  }
3171
3181
  routes2.push({
3172
- pattern: route.path,
3182
+ pattern: "/" + joinPath([...parts, ...splitPath(route.path)]),
3173
3183
  meta: {
3174
3184
  redirect
3175
3185
  }
@@ -3182,15 +3192,15 @@ function RouterStore(ctx) {
3182
3192
  } else if (route.view) {
3183
3193
  throw new TypeError(`Route '${route.path}' expected a view function or undefined. Got: ${route.view}`);
3184
3194
  }
3195
+ const markup = m(view);
3196
+ const layer = { id: layerId++, markup };
3185
3197
  if (route.routes) {
3186
3198
  for (const subroute of route.routes) {
3187
- routes2.push(...prepareRoute(subroute));
3199
+ routes2.push(...prepareRoute(subroute, [...parents, route], [...layers, layer]));
3188
3200
  }
3189
3201
  } else {
3190
- const markup = m(view);
3191
- const layer = { id: layerId++, markup };
3192
3202
  routes2.push({
3193
- pattern: route.path,
3203
+ pattern: parent ? joinPath([...parents.map((p) => p.path), route.path]) : route.path,
3194
3204
  meta: {
3195
3205
  pattern: route.path,
3196
3206
  layers: [...layers, layer],
@@ -3228,7 +3238,7 @@ function RouterStore(ctx) {
3228
3238
  }
3229
3239
  }
3230
3240
  ctx.onConnected(() => {
3231
- ctx.info(`Total routes: ${routes.length}`);
3241
+ ctx.info("Routes registered:", routes);
3232
3242
  });
3233
3243
  const $$pattern = $$(null);
3234
3244
  const $$path = $$("");
@@ -3252,8 +3262,10 @@ function RouterStore(ctx) {
3252
3262
  ctx.onConnected(() => {
3253
3263
  history.listen(onRouteChange);
3254
3264
  onRouteChange(history);
3265
+ ctx.info("Intercepting <a> clicks within root element:", appContext.rootElement);
3255
3266
  catchLinks(appContext.rootElement, (anchor) => {
3256
3267
  let href = anchor.getAttribute("href");
3268
+ ctx.info("Intercepted link click", anchor, href);
3257
3269
  if (!/^https?:\/\/|^\//.test(href)) {
3258
3270
  href = joinPath([history.location.pathname, href]);
3259
3271
  }
@@ -3315,7 +3327,7 @@ function RouterStore(ctx) {
3315
3327
  }
3316
3328
  });
3317
3329
  }
3318
- ctx.info(`Matched route: '${matched.pattern}'`);
3330
+ ctx.info(`Matched route: '${matched.pattern}' ('${matched.path}')`);
3319
3331
  if (matched.meta.redirect != null) {
3320
3332
  if (typeof matched.meta.redirect === "string") {
3321
3333
  let path = matched.meta.redirect;
@@ -3339,22 +3351,20 @@ function RouterStore(ctx) {
3339
3351
  const matchedLayer = layers[i];
3340
3352
  const activeLayer = activeLayers[i];
3341
3353
  if (activeLayer?.id !== matchedLayer.id) {
3342
- ctx.info(`Replacing layer ${i} (active ID: ${activeLayer?.id}, matched ID: ${matchedLayer.id})`);
3354
+ ctx.info(`Replacing layer @${i} (active ID: ${activeLayer?.id}, matched ID: ${matchedLayer.id})`);
3343
3355
  activeLayers = activeLayers.slice(0, i);
3344
3356
  const parentLayer = activeLayers[activeLayers.length - 1];
3345
3357
  const renderContext = { appContext, elementContext };
3346
3358
  const rendered = renderMarkupToDOM(matchedLayer.markup, renderContext);
3347
3359
  const handle = getRenderHandle(rendered);
3348
- render.update(() => {
3349
- if (activeLayer && activeLayer.handle.connected) {
3350
- activeLayer.handle.disconnect();
3351
- }
3352
- if (parentLayer) {
3353
- parentLayer.handle.setChildren(rendered);
3354
- } else {
3355
- appContext.rootView.setChildren(rendered);
3356
- }
3357
- }, "dolla-router-change");
3360
+ if (activeLayer && activeLayer.handle.connected) {
3361
+ activeLayer.handle.disconnect();
3362
+ }
3363
+ if (parentLayer) {
3364
+ parentLayer.handle.setChildren(rendered);
3365
+ } else {
3366
+ appContext.rootView.setChildren(rendered);
3367
+ }
3358
3368
  activeLayers.push({ id: matchedLayer.id, handle });
3359
3369
  }
3360
3370
  }