@archie/devtools 0.1.13 → 0.1.14

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.
@@ -46,8 +46,22 @@ type InjectOptions = {
46
46
  localScriptUrl?: string;
47
47
  };
48
48
 
49
+ type ArchieRouteFrame = 'phone' | 'tablet' | 'desktop';
50
+ /**
51
+ * Whitelisted subset of a React Router `handle` that is forwarded in
52
+ * ARCHIE_ROUTE_UPDATE. The router's `handle` is free-form (functions, React
53
+ * elements...) and is NOT structured-cloneable in general, so only `surface`
54
+ * (non-empty string) and `frame` ('phone' | 'tablet' | 'desktop') are copied;
55
+ * any other key and any invalid value is dropped. When neither survives the
56
+ * `handle` key is omitted from the entry entirely.
57
+ */
58
+ type ArchieRouteHandle = {
59
+ surface?: string;
60
+ frame?: ArchieRouteFrame;
61
+ };
49
62
  interface ArchieRouteObjectLike {
50
63
  id?: string;
64
+ handle?: unknown;
51
65
  path?: string;
52
66
  index?: boolean;
53
67
  Component?: unknown;
@@ -58,6 +72,7 @@ interface ArchieRouteObjectLike {
58
72
  interface ArchieRouteMatchLike {
59
73
  route: {
60
74
  id?: string;
75
+ handle?: unknown;
61
76
  };
62
77
  pathname: string;
63
78
  params: Record<string, string | undefined>;
@@ -84,6 +99,46 @@ interface ArchieRouterLike {
84
99
  }): Promise<void> | void;
85
100
  subscribe(listener: (state: ArchieRouterStateLike) => void): () => void;
86
101
  }
102
+ /**
103
+ * Route information for the sitemap
104
+ */
105
+ interface ArchieGuardEvidence {
106
+ componentName: string;
107
+ roles?: string[];
108
+ source: 'self' | 'ancestor';
109
+ ancestorId?: string;
110
+ }
111
+ interface RouteInfo {
112
+ id: string | undefined;
113
+ path: string;
114
+ handle?: ArchieRouteHandle;
115
+ hasChildren: boolean;
116
+ parentId: string | null;
117
+ index: boolean;
118
+ isLayout: boolean;
119
+ componentName: string | null;
120
+ guardEvidence: ArchieGuardEvidence[];
121
+ }
122
+ /**
123
+ * Type definition for the route update message
124
+ */
125
+ interface ArchieRouteUpdateMessage {
126
+ type: 'ARCHIE_ROUTE_UPDATE';
127
+ payload: {
128
+ path: string;
129
+ search: string;
130
+ hash: string;
131
+ matches: Array<{
132
+ id: string | undefined;
133
+ pathname: string;
134
+ params: Record<string, string | undefined>;
135
+ handle?: ArchieRouteHandle;
136
+ }>;
137
+ allRoutes: RouteInfo[];
138
+ layoutRoutes: RouteInfo[];
139
+ timestamp: number;
140
+ };
141
+ }
87
142
 
88
143
  interface ArchieDevToolsRuntimeOptions {
89
144
  router: ArchieRouterLike;
@@ -103,4 +158,4 @@ interface DndProviderProps {
103
158
  }
104
159
  declare function DndProvider({ children }: DndProviderProps): react_jsx_runtime.JSX.Element;
105
160
 
106
- export { ArchieDevToolProvider, type ArchieDevToolProviderProps, DndProvider };
161
+ export { ArchieDevToolProvider, type ArchieDevToolProviderProps, type ArchieRouteFrame, type ArchieRouteHandle, type ArchieRouteUpdateMessage, DndProvider, type RouteInfo };
@@ -46,8 +46,22 @@ type InjectOptions = {
46
46
  localScriptUrl?: string;
47
47
  };
48
48
 
49
+ type ArchieRouteFrame = 'phone' | 'tablet' | 'desktop';
50
+ /**
51
+ * Whitelisted subset of a React Router `handle` that is forwarded in
52
+ * ARCHIE_ROUTE_UPDATE. The router's `handle` is free-form (functions, React
53
+ * elements...) and is NOT structured-cloneable in general, so only `surface`
54
+ * (non-empty string) and `frame` ('phone' | 'tablet' | 'desktop') are copied;
55
+ * any other key and any invalid value is dropped. When neither survives the
56
+ * `handle` key is omitted from the entry entirely.
57
+ */
58
+ type ArchieRouteHandle = {
59
+ surface?: string;
60
+ frame?: ArchieRouteFrame;
61
+ };
49
62
  interface ArchieRouteObjectLike {
50
63
  id?: string;
64
+ handle?: unknown;
51
65
  path?: string;
52
66
  index?: boolean;
53
67
  Component?: unknown;
@@ -58,6 +72,7 @@ interface ArchieRouteObjectLike {
58
72
  interface ArchieRouteMatchLike {
59
73
  route: {
60
74
  id?: string;
75
+ handle?: unknown;
61
76
  };
62
77
  pathname: string;
63
78
  params: Record<string, string | undefined>;
@@ -84,6 +99,46 @@ interface ArchieRouterLike {
84
99
  }): Promise<void> | void;
85
100
  subscribe(listener: (state: ArchieRouterStateLike) => void): () => void;
86
101
  }
102
+ /**
103
+ * Route information for the sitemap
104
+ */
105
+ interface ArchieGuardEvidence {
106
+ componentName: string;
107
+ roles?: string[];
108
+ source: 'self' | 'ancestor';
109
+ ancestorId?: string;
110
+ }
111
+ interface RouteInfo {
112
+ id: string | undefined;
113
+ path: string;
114
+ handle?: ArchieRouteHandle;
115
+ hasChildren: boolean;
116
+ parentId: string | null;
117
+ index: boolean;
118
+ isLayout: boolean;
119
+ componentName: string | null;
120
+ guardEvidence: ArchieGuardEvidence[];
121
+ }
122
+ /**
123
+ * Type definition for the route update message
124
+ */
125
+ interface ArchieRouteUpdateMessage {
126
+ type: 'ARCHIE_ROUTE_UPDATE';
127
+ payload: {
128
+ path: string;
129
+ search: string;
130
+ hash: string;
131
+ matches: Array<{
132
+ id: string | undefined;
133
+ pathname: string;
134
+ params: Record<string, string | undefined>;
135
+ handle?: ArchieRouteHandle;
136
+ }>;
137
+ allRoutes: RouteInfo[];
138
+ layoutRoutes: RouteInfo[];
139
+ timestamp: number;
140
+ };
141
+ }
87
142
 
88
143
  interface ArchieDevToolsRuntimeOptions {
89
144
  router: ArchieRouterLike;
@@ -103,4 +158,4 @@ interface DndProviderProps {
103
158
  }
104
159
  declare function DndProvider({ children }: DndProviderProps): react_jsx_runtime.JSX.Element;
105
160
 
106
- export { ArchieDevToolProvider, type ArchieDevToolProviderProps, DndProvider };
161
+ export { ArchieDevToolProvider, type ArchieDevToolProviderProps, type ArchieRouteFrame, type ArchieRouteHandle, type ArchieRouteUpdateMessage, DndProvider, type RouteInfo };
@@ -10271,7 +10271,7 @@ function isPreviewOrigin(origin) {
10271
10271
  var DEFAULT_SCRIPT_ID = "archie-inspector-script";
10272
10272
  var R2_INSPECTOR_BASE_URL = "https://pub-bf238c278d9644b39ec34ecaca1d315c.r2.dev";
10273
10273
  function readBuildVersion() {
10274
- return "0.1.13" ? "0.1.13" : null;
10274
+ return "0.1.14" ? "0.1.14" : null;
10275
10275
  }
10276
10276
  var REMOTE_INSPECTOR_VERSION = readBuildVersion();
10277
10277
  var isRemoteInspectorUrlVersioned = REMOTE_INSPECTOR_VERSION !== null;
@@ -10475,6 +10475,23 @@ async function captureDomSnapshot() {
10475
10475
  }
10476
10476
 
10477
10477
  // src/client/route-listener/routeListener.ts
10478
+ var ROUTE_FRAMES = ["phone", "tablet", "desktop"];
10479
+ function pickRouteHandle(h) {
10480
+ try {
10481
+ if (typeof h !== "object" || h === null) return void 0;
10482
+ const raw = h;
10483
+ const surface = raw.surface;
10484
+ const frame = raw.frame;
10485
+ const out = {};
10486
+ if (typeof surface === "string" && surface !== "") out.surface = surface;
10487
+ if (typeof frame === "string" && ROUTE_FRAMES.includes(frame)) {
10488
+ out.frame = frame;
10489
+ }
10490
+ return out.surface !== void 0 || out.frame !== void 0 ? out : void 0;
10491
+ } catch {
10492
+ return void 0;
10493
+ }
10494
+ }
10478
10495
  var GUARD_NAME_RE = /guard|protect|require|auth(?!or)/i;
10479
10496
  var GUARD_PRIVATE_RE = /\bprivate|Private(?=[A-Z]|$)/;
10480
10497
  var NON_GUARD_SUFFIX_RE = /(Layout|Provider|Context|Page|Form|Screen|View)$/;
@@ -10544,10 +10561,12 @@ function extractAllRoutes(routes, parentPath = "", parentId = null, inheritedGua
10544
10561
  const isLayout = !route.path && !route.index && hasChildren;
10545
10562
  const own = [];
10546
10563
  collectGuards(route.element, 0, own);
10564
+ const handle = pickRouteHandle(route.handle);
10547
10565
  if (route.path !== void 0 || route.index || isLayout) {
10548
10566
  result.push({
10549
10567
  id: route.id,
10550
10568
  path: route.index ? parentPath || "/" : path,
10569
+ ...handle ? { handle } : {},
10551
10570
  hasChildren,
10552
10571
  parentId,
10553
10572
  index: !!route.index,
@@ -10590,11 +10609,15 @@ function broadcastRouteState(target, state, routes) {
10590
10609
  path: state.location.pathname,
10591
10610
  search: state.location.search,
10592
10611
  hash: state.location.hash,
10593
- matches: state.matches.map((m) => ({
10594
- id: m.route.id,
10595
- pathname: m.pathname,
10596
- params: m.params
10597
- })),
10612
+ matches: state.matches.map((m) => {
10613
+ const handle = pickRouteHandle(m.route.handle);
10614
+ return {
10615
+ id: m.route.id,
10616
+ pathname: m.pathname,
10617
+ params: m.params,
10618
+ ...handle ? { handle } : {}
10619
+ };
10620
+ }),
10598
10621
  // Layouts stay out of allRoutes so consumers that predate them don't list duplicates.
10599
10622
  allRoutes: routes.filter((r) => !r.isLayout),
10600
10623
  layoutRoutes: routes.filter((r) => r.isLayout),
@@ -10609,7 +10632,7 @@ var SETTLE_QUIET_MS = 400;
10609
10632
  var SETTLE_TIMEOUT_MS = 8e3;
10610
10633
  var SETTLE_POLL_MS = 50;
10611
10634
  function readPackageVersion() {
10612
- return true ? "0.1.13" : "unknown";
10635
+ return true ? "0.1.14" : "unknown";
10613
10636
  }
10614
10637
  var DEFAULT_ARCHIE_COMMAND_ORIGINS = getAllowedOrigins(true);
10615
10638
  function originPatternToRegExp(pattern) {
@@ -10236,7 +10236,7 @@ function isPreviewOrigin(origin) {
10236
10236
  var DEFAULT_SCRIPT_ID = "archie-inspector-script";
10237
10237
  var R2_INSPECTOR_BASE_URL = "https://pub-bf238c278d9644b39ec34ecaca1d315c.r2.dev";
10238
10238
  function readBuildVersion() {
10239
- return "0.1.13" ? "0.1.13" : null;
10239
+ return "0.1.14" ? "0.1.14" : null;
10240
10240
  }
10241
10241
  var REMOTE_INSPECTOR_VERSION = readBuildVersion();
10242
10242
  var isRemoteInspectorUrlVersioned = REMOTE_INSPECTOR_VERSION !== null;
@@ -10440,6 +10440,23 @@ async function captureDomSnapshot() {
10440
10440
  }
10441
10441
 
10442
10442
  // src/client/route-listener/routeListener.ts
10443
+ var ROUTE_FRAMES = ["phone", "tablet", "desktop"];
10444
+ function pickRouteHandle(h) {
10445
+ try {
10446
+ if (typeof h !== "object" || h === null) return void 0;
10447
+ const raw = h;
10448
+ const surface = raw.surface;
10449
+ const frame = raw.frame;
10450
+ const out = {};
10451
+ if (typeof surface === "string" && surface !== "") out.surface = surface;
10452
+ if (typeof frame === "string" && ROUTE_FRAMES.includes(frame)) {
10453
+ out.frame = frame;
10454
+ }
10455
+ return out.surface !== void 0 || out.frame !== void 0 ? out : void 0;
10456
+ } catch {
10457
+ return void 0;
10458
+ }
10459
+ }
10443
10460
  var GUARD_NAME_RE = /guard|protect|require|auth(?!or)/i;
10444
10461
  var GUARD_PRIVATE_RE = /\bprivate|Private(?=[A-Z]|$)/;
10445
10462
  var NON_GUARD_SUFFIX_RE = /(Layout|Provider|Context|Page|Form|Screen|View)$/;
@@ -10509,10 +10526,12 @@ function extractAllRoutes(routes, parentPath = "", parentId = null, inheritedGua
10509
10526
  const isLayout = !route.path && !route.index && hasChildren;
10510
10527
  const own = [];
10511
10528
  collectGuards(route.element, 0, own);
10529
+ const handle = pickRouteHandle(route.handle);
10512
10530
  if (route.path !== void 0 || route.index || isLayout) {
10513
10531
  result.push({
10514
10532
  id: route.id,
10515
10533
  path: route.index ? parentPath || "/" : path,
10534
+ ...handle ? { handle } : {},
10516
10535
  hasChildren,
10517
10536
  parentId,
10518
10537
  index: !!route.index,
@@ -10555,11 +10574,15 @@ function broadcastRouteState(target, state, routes) {
10555
10574
  path: state.location.pathname,
10556
10575
  search: state.location.search,
10557
10576
  hash: state.location.hash,
10558
- matches: state.matches.map((m) => ({
10559
- id: m.route.id,
10560
- pathname: m.pathname,
10561
- params: m.params
10562
- })),
10577
+ matches: state.matches.map((m) => {
10578
+ const handle = pickRouteHandle(m.route.handle);
10579
+ return {
10580
+ id: m.route.id,
10581
+ pathname: m.pathname,
10582
+ params: m.params,
10583
+ ...handle ? { handle } : {}
10584
+ };
10585
+ }),
10563
10586
  // Layouts stay out of allRoutes so consumers that predate them don't list duplicates.
10564
10587
  allRoutes: routes.filter((r) => !r.isLayout),
10565
10588
  layoutRoutes: routes.filter((r) => r.isLayout),
@@ -10574,7 +10597,7 @@ var SETTLE_QUIET_MS = 400;
10574
10597
  var SETTLE_TIMEOUT_MS = 8e3;
10575
10598
  var SETTLE_POLL_MS = 50;
10576
10599
  function readPackageVersion() {
10577
- return true ? "0.1.13" : "unknown";
10600
+ return true ? "0.1.14" : "unknown";
10578
10601
  }
10579
10602
  var DEFAULT_ARCHIE_COMMAND_ORIGINS = getAllowedOrigins(true);
10580
10603
  function originPatternToRegExp(pattern) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@archie/devtools",
3
- "version": "0.1.13",
3
+ "version": "0.1.14",
4
4
  "description": "DevTools for Archie generated applications - Route synchronization and editor communication",
5
5
  "sideEffects": false,
6
6
  "repository": {