@emkodev/emroute 1.7.0 → 1.7.1-beta.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/dist/emroute.js CHANGED
@@ -1670,7 +1670,61 @@ var Runtime = class {
1670
1670
  }
1671
1671
  /** Write. Defaults to PUT; pass `{ method: "DELETE" }` etc. to override. */
1672
1672
  command(resource, options) {
1673
- return this.handle(resource, { method: "PUT", ...options });
1673
+ const path = typeof resource === "string" ? resource : new URL(resource instanceof Request ? resource.url : resource.toString()).pathname;
1674
+ const result = this.handle(resource, { method: "PUT", ...options });
1675
+ const routesDir = this.config.routesDir ?? DEFAULT_ROUTES_DIR;
1676
+ if (path.startsWith(routesDir + "/")) {
1677
+ return result.then(async (res) => {
1678
+ await this.mergeRouteIntoManifest(path, routesDir);
1679
+ return res;
1680
+ });
1681
+ }
1682
+ return result;
1683
+ }
1684
+ /**
1685
+ * Parse a single route file path and merge it into the stored manifest.
1686
+ * Avoids a full directory rescan — just reads the current manifest,
1687
+ * inserts the new entry, and writes it back.
1688
+ */
1689
+ async mergeRouteIntoManifest(filePath, routesDir) {
1690
+ const relativePath = filePath.slice(routesDir.length + 1);
1691
+ const parts = relativePath.split("/");
1692
+ const filename = parts[parts.length - 1];
1693
+ const dirSegments = parts.slice(0, -1);
1694
+ const match = filename.match(/^(.+?)\.(page|error|redirect)\.(ts|js|html|md|css)$/);
1695
+ if (!match)
1696
+ return;
1697
+ const [, name, kind, ext] = match;
1698
+ const response = await this.handle(ROUTES_MANIFEST_PATH);
1699
+ const tree = response.status === 404 ? {} : await response.json();
1700
+ let node = tree;
1701
+ for (const dir of dirSegments) {
1702
+ if (dir.startsWith("[") && dir.endsWith("]")) {
1703
+ const param = dir.slice(1, -1);
1704
+ node.dynamic ??= { param, child: {} };
1705
+ node = node.dynamic.child;
1706
+ } else {
1707
+ node.children ??= {};
1708
+ node.children[dir] ??= {};
1709
+ node = node.children[dir];
1710
+ }
1711
+ }
1712
+ if (kind === "error") {
1713
+ node.errorBoundary = filePath;
1714
+ } else {
1715
+ const target = resolveTargetNode(node, name, dirSegments.length === 0);
1716
+ if (kind === "redirect") {
1717
+ target.redirect = filePath;
1718
+ } else {
1719
+ target.files ??= {};
1720
+ target.files[ext] = filePath;
1721
+ }
1722
+ }
1723
+ this.routesManifestCache = null;
1724
+ await this.handle(ROUTES_MANIFEST_PATH, {
1725
+ method: "PUT",
1726
+ body: JSON.stringify(tree)
1727
+ });
1674
1728
  }
1675
1729
  /**
1676
1730
  * Dynamically import a module from this runtime's storage.