@vesk/vesk-cli 0.2.64 → 0.2.65

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.
Files changed (2) hide show
  1. package/dist/cli.js +1158 -34
  2. package/package.json +5 -5
package/dist/cli.js CHANGED
@@ -22494,6 +22494,7 @@ __export(server_utils_exports, {
22494
22494
  escapeHtml: () => escapeHtml,
22495
22495
  evalTopLevelCode: () => evalTopLevelCode,
22496
22496
  exprJS: () => exprJS,
22497
+ extractRuntimeBindingPairs: () => extractRuntimeBindingPairs,
22497
22498
  extractRuntimeNames: () => extractRuntimeNames,
22498
22499
  extractTopLevelNames: () => extractTopLevelNames,
22499
22500
  getClientIp: () => getClientIp,
@@ -23281,33 +23282,39 @@ function tryParseTopLevel(code) {
23281
23282
  return null;
23282
23283
  }
23283
23284
  }
23284
- function extractRuntimeNames(importStrs) {
23285
- const names = [];
23285
+ function extractRuntimeBindingPairs(importStrs) {
23286
+ const pairs = [];
23287
+ const isRuntimeTarget = (src2) => src2 === "@vesk/runtime" || src2 === "@vesk/reactivity" || src2.startsWith("@vesk/runtime/");
23286
23288
  for (const imp of importStrs) {
23287
23289
  const ast = tryParseImport(imp);
23288
23290
  if (ast) {
23289
23291
  for (const stmt of ast.body) {
23290
23292
  if (stmt.type !== "ImportDeclaration") continue;
23293
+ if (stmt.importKind === "type") continue;
23291
23294
  const src2 = stmt.source?.value;
23292
- if (typeof src2 !== "string" || src2 !== "@vesk/runtime" && src2 !== "@vesk/reactivity") continue;
23295
+ if (typeof src2 !== "string" || !isRuntimeTarget(src2)) continue;
23293
23296
  for (const spec of stmt.specifiers || []) {
23294
23297
  if (spec.importKind === "type") continue;
23295
23298
  if (spec.type === "ImportSpecifier") {
23296
- const name = spec.local?.name || spec.imported?.name;
23297
- if (name) names.push(name);
23299
+ const local = spec.local?.name;
23300
+ const imported = spec.imported?.name;
23301
+ if (local) pairs.push({ imported: imported || local, local });
23298
23302
  } else if (spec.type === "ImportDefaultSpecifier" || spec.type === "ImportNamespaceSpecifier") {
23299
- if (spec.local?.name) names.push(spec.local.name);
23303
+ if (spec.local?.name) pairs.push({ imported: "*", local: spec.local.name });
23300
23304
  }
23301
23305
  }
23302
23306
  }
23303
23307
  continue;
23304
23308
  }
23305
23309
  const target = importModuleTarget(imp);
23306
- if (target === "@vesk/runtime" || target === "@vesk/reactivity") {
23307
- for (const name of extractImportNames(imp)) names.push(name);
23310
+ if (target && isRuntimeTarget(target)) {
23311
+ for (const name of extractImportNames(imp)) pairs.push({ imported: name, local: name });
23308
23312
  }
23309
23313
  }
23310
- return names;
23314
+ return pairs;
23315
+ }
23316
+ function extractRuntimeNames(importStrs) {
23317
+ return extractRuntimeBindingPairs(importStrs).map((p) => p.local);
23311
23318
  }
23312
23319
  function tryParseImport(code) {
23313
23320
  try {
@@ -23348,7 +23355,7 @@ function setRuntimeModule(mod) {
23348
23355
  __cachedRuntimeModule = mod;
23349
23356
  }
23350
23357
  function loadRuntimeImports(importStrs) {
23351
- const names = extractRuntimeNames(importStrs);
23358
+ const pairs = extractRuntimeBindingPairs(importStrs);
23352
23359
  const mod = __cachedRuntimeModule || index_server_exports;
23353
23360
  if (mod) {
23354
23361
  const result = {};
@@ -23357,8 +23364,12 @@ function loadRuntimeImports(importStrs) {
23357
23364
  for (const name of ["get", "set", "track"]) {
23358
23365
  if (name in mod) result[name] = mod[name];
23359
23366
  }
23360
- for (const name of names) {
23361
- if (name in mod) result[name] = mod[name];
23367
+ for (const { imported, local } of pairs) {
23368
+ if (imported === "*") {
23369
+ result[local] = mod;
23370
+ } else if (imported in mod) {
23371
+ result[local] = mod[imported];
23372
+ }
23362
23373
  }
23363
23374
  return result;
23364
23375
  }
@@ -27755,6 +27766,1019 @@ var init_nested_update = __esm({
27755
27766
  }
27756
27767
  });
27757
27768
 
27769
+ // ../runtime/src/store-persistence.ts
27770
+ function currentSsrToken() {
27771
+ const g4 = globalThis;
27772
+ return typeof g4.__vsk_ssr_token === "string" ? g4.__vsk_ssr_token : "";
27773
+ }
27774
+ function persistedStoreCookieName(storageKey) {
27775
+ return "vsk_store_" + encodeURIComponent(storageKey);
27776
+ }
27777
+ function bucketFor(token) {
27778
+ const set2 = pendingKeys.get(token);
27779
+ if (set2) return set2;
27780
+ const fresh = /* @__PURE__ */ new Set();
27781
+ pendingKeys.set(token, fresh);
27782
+ return fresh;
27783
+ }
27784
+ function readPersistedStorage(storageKey) {
27785
+ if (!storageKey) return null;
27786
+ if (typeof window === "undefined") {
27787
+ bucketFor(currentSsrToken()).add(storageKey);
27788
+ return serverReadHook ? serverReadHook(storageKey) ?? null : null;
27789
+ }
27790
+ const init = globalThis.__VESK_STORE_INIT__;
27791
+ if (init && init[storageKey] !== void 0) {
27792
+ const raw2 = init[storageKey];
27793
+ delete init[storageKey];
27794
+ try {
27795
+ localStorage.setItem(storageKey, raw2);
27796
+ } catch {
27797
+ }
27798
+ return raw2;
27799
+ }
27800
+ try {
27801
+ return localStorage.getItem(storageKey);
27802
+ } catch {
27803
+ return null;
27804
+ }
27805
+ }
27806
+ function writePersistedStorage(storageKey, raw2) {
27807
+ if (!storageKey) return;
27808
+ if (typeof window !== "undefined") {
27809
+ try {
27810
+ localStorage.setItem(storageKey, raw2);
27811
+ } catch {
27812
+ }
27813
+ }
27814
+ if (typeof document !== "undefined") {
27815
+ try {
27816
+ document.cookie = persistedStoreCookieName(storageKey) + "=" + encodeURIComponent(raw2) + "; path=/; max-age=31536000; SameSite=Lax";
27817
+ } catch {
27818
+ }
27819
+ }
27820
+ }
27821
+ function clearPersistedStorage(storageKey) {
27822
+ if (!storageKey) return;
27823
+ if (typeof window !== "undefined") {
27824
+ try {
27825
+ localStorage.removeItem(storageKey);
27826
+ } catch {
27827
+ }
27828
+ }
27829
+ if (typeof document !== "undefined") {
27830
+ try {
27831
+ document.cookie = persistedStoreCookieName(storageKey) + "=; path=/; max-age=0";
27832
+ } catch {
27833
+ }
27834
+ }
27835
+ }
27836
+ var serverReadHook, pendingKeys;
27837
+ var init_store_persistence = __esm({
27838
+ "../runtime/src/store-persistence.ts"() {
27839
+ "use strict";
27840
+ serverReadHook = null;
27841
+ pendingKeys = /* @__PURE__ */ new Map();
27842
+ }
27843
+ });
27844
+
27845
+ // ../runtime/src/store.ts
27846
+ function cloneState(value) {
27847
+ return Array.isArray(value) ? value.slice() : { ...value };
27848
+ }
27849
+ function createStore(initial, options = {}) {
27850
+ const { persist = false, storageKey, devtools = false } = options;
27851
+ let value = cloneState(initial);
27852
+ if (persist && storageKey) {
27853
+ const stored = readPersistedStorage(storageKey);
27854
+ if (stored) {
27855
+ try {
27856
+ value = JSON.parse(stored);
27857
+ } catch {
27858
+ }
27859
+ }
27860
+ }
27861
+ const stateCell = track(value);
27862
+ const subs = /* @__PURE__ */ new Set();
27863
+ const watchers = [];
27864
+ const middlewares = [];
27865
+ let prevValue = cloneState(value);
27866
+ let batchDepth = 0;
27867
+ let dirty = false;
27868
+ function notifyNow(action, payload) {
27869
+ const current2 = stateCell.get();
27870
+ if (current2 === prevValue) return;
27871
+ subs.forEach((fn) => fn(current2));
27872
+ watchers.forEach(({ selector, cb, equals }) => {
27873
+ const eq = equals ?? Object.is;
27874
+ const newVal = selector(current2);
27875
+ const oldVal = selector(prevValue);
27876
+ if (!eq(newVal, oldVal)) cb(newVal, oldVal);
27877
+ });
27878
+ middlewares.forEach((fn) => fn(current2, action, payload));
27879
+ if (devtools && typeof window !== "undefined") {
27880
+ const dt = window.__VESK_STORE_DEVTOOLS__;
27881
+ if (dt && typeof dt.send === "function") {
27882
+ dt.send({ type: action, payload, state: structuredClone(current2) });
27883
+ }
27884
+ }
27885
+ prevValue = cloneState(current2);
27886
+ }
27887
+ function notifyDirty(action, payload) {
27888
+ if (batchDepth > 0) {
27889
+ dirty = true;
27890
+ } else {
27891
+ notifyNow(action, payload);
27892
+ }
27893
+ }
27894
+ function persistToStorage() {
27895
+ if (persist && storageKey) {
27896
+ try {
27897
+ writePersistedStorage(storageKey, JSON.stringify(stateCell.get()));
27898
+ } catch (err) {
27899
+ console.log("error saving to localStorage: ", err);
27900
+ }
27901
+ }
27902
+ }
27903
+ function get2() {
27904
+ return stateCell.get();
27905
+ }
27906
+ function set2(next, action = "set") {
27907
+ stateCell.set(next);
27908
+ persistToStorage();
27909
+ notifyDirty(action, next);
27910
+ }
27911
+ function update(partialOrFn, action = "update") {
27912
+ const current2 = stateCell.get();
27913
+ const patch = typeof partialOrFn === "function" ? partialOrFn(current2) : partialOrFn;
27914
+ const next = Object.assign(cloneState(current2), patch);
27915
+ stateCell.set(next);
27916
+ persistToStorage();
27917
+ notifyDirty(action, patch);
27918
+ }
27919
+ function deleteKeys(keys, action = "delete") {
27920
+ const current2 = stateCell.get();
27921
+ const kArray = Array.isArray(keys) ? keys : [keys];
27922
+ const next = cloneState(current2);
27923
+ kArray.forEach((k) => {
27924
+ delete next[k];
27925
+ });
27926
+ stateCell.set(next);
27927
+ persistToStorage();
27928
+ notifyDirty(action, keys);
27929
+ }
27930
+ function reset2() {
27931
+ stateCell.set(cloneState(initial));
27932
+ notifyDirty("reset");
27933
+ }
27934
+ function rehydrate(newInitial) {
27935
+ Object.assign(initial, newInitial);
27936
+ stateCell.set(cloneState(initial));
27937
+ notifyDirty("rehydrate");
27938
+ }
27939
+ function clear() {
27940
+ stateCell.set(cloneState(initial));
27941
+ if (persist && storageKey) {
27942
+ clearPersistedStorage(storageKey);
27943
+ }
27944
+ notifyDirty("clear");
27945
+ }
27946
+ function batch(fn) {
27947
+ batchDepth++;
27948
+ try {
27949
+ return flush_sync(fn);
27950
+ } finally {
27951
+ batchDepth--;
27952
+ if (batchDepth === 0 && dirty) {
27953
+ notifyDirty("batch");
27954
+ dirty = false;
27955
+ }
27956
+ }
27957
+ }
27958
+ function subscribe(fn, selector, equals) {
27959
+ const eq = equals ?? Object.is;
27960
+ let hasPrev = false;
27961
+ let prev;
27962
+ const wrapper = selector ? (state) => {
27963
+ const selected = selector(state);
27964
+ if (!hasPrev || !eq(selected, prev)) {
27965
+ hasPrev = true;
27966
+ prev = selected;
27967
+ fn(selected);
27968
+ }
27969
+ } : fn;
27970
+ subs.add(wrapper);
27971
+ wrapper(stateCell.get());
27972
+ return () => subs.delete(wrapper);
27973
+ }
27974
+ function watch2(selector, callback, equals) {
27975
+ watchers.push({ selector, cb: callback, equals });
27976
+ return () => {
27977
+ const i = watchers.findIndex((w) => w.cb === callback);
27978
+ if (i >= 0) watchers.splice(i, 1);
27979
+ };
27980
+ }
27981
+ function use(middleware) {
27982
+ middlewares.push(middleware);
27983
+ return () => {
27984
+ const i = middlewares.indexOf(middleware);
27985
+ if (i >= 0) middlewares.splice(i, 1);
27986
+ };
27987
+ }
27988
+ function derive(selector, equals) {
27989
+ return {
27990
+ subscribe(cb) {
27991
+ return subscribe(
27992
+ (v) => cb(v),
27993
+ selector,
27994
+ equals
27995
+ );
27996
+ }
27997
+ };
27998
+ }
27999
+ function toJSON() {
28000
+ return structuredClone(stateCell.get());
28001
+ }
28002
+ return {
28003
+ get: get2,
28004
+ set: set2,
28005
+ update,
28006
+ delete: deleteKeys,
28007
+ clear,
28008
+ subscribe,
28009
+ watch: watch2,
28010
+ use,
28011
+ derive,
28012
+ batch,
28013
+ reset: reset2,
28014
+ rehydrate,
28015
+ toJSON
28016
+ };
28017
+ }
28018
+ var init_store = __esm({
28019
+ "../runtime/src/store.ts"() {
28020
+ "use strict";
28021
+ init_ripple_runtime();
28022
+ init_store_persistence();
28023
+ }
28024
+ });
28025
+
28026
+ // ../runtime/src/path-store.ts
28027
+ function isObject2(value) {
28028
+ return value !== null && typeof value === "object";
28029
+ }
28030
+ function isDigits(s) {
28031
+ if (s.length === 0) return false;
28032
+ for (let i = 0; i < s.length; i++) {
28033
+ const c = s.charCodeAt(i);
28034
+ if (c < 48 || c > 57) return false;
28035
+ }
28036
+ return true;
28037
+ }
28038
+ function parseStorePath(input) {
28039
+ const tokens = [];
28040
+ let i = 0;
28041
+ const n = input.length;
28042
+ const readBracketed = () => {
28043
+ i++;
28044
+ let start = i;
28045
+ while (i < n && input[i] >= "0" && input[i] <= "9") i++;
28046
+ if (start === i || input[i] !== "]") {
28047
+ throw new Error(`Path store: bad index in path "${input}"`);
28048
+ }
28049
+ tokens.push(Number(input.slice(start, i)));
28050
+ i++;
28051
+ };
28052
+ while (i < n) {
28053
+ const c = input[i];
28054
+ if (c === ".") {
28055
+ i++;
28056
+ continue;
28057
+ }
28058
+ if (c === "[") {
28059
+ readBracketed();
28060
+ continue;
28061
+ }
28062
+ let start = i;
28063
+ while (i < n && input[i] !== "." && input[i] !== "[") i++;
28064
+ tokens.push(input.slice(start, i));
28065
+ }
28066
+ return tokens;
28067
+ }
28068
+ function pathKey(tokens) {
28069
+ return tokens.join("\0");
28070
+ }
28071
+ function tokensOfKey(key) {
28072
+ if (key === "") return [];
28073
+ return key.split("\0").map((t) => isDigits(t) ? Number(t) : t);
28074
+ }
28075
+ function isPrefix(prefix, full) {
28076
+ if (prefix.length > full.length) return false;
28077
+ for (let i = 0; i < prefix.length; i++) {
28078
+ if (String(prefix[i]) !== String(full[i])) return false;
28079
+ }
28080
+ return true;
28081
+ }
28082
+ function isStrictPrefix(prefix, full) {
28083
+ return prefix.length > 0 && prefix.length < full.length && isPrefix(prefix, full);
28084
+ }
28085
+ function cloneValue(value, seen) {
28086
+ if (value === null || typeof value !== "object") return value;
28087
+ seen = seen ?? /* @__PURE__ */ new Map();
28088
+ const existing = seen.get(value);
28089
+ if (existing !== void 0) return existing;
28090
+ if (value instanceof Date) {
28091
+ const d = new Date(value.getTime());
28092
+ seen.set(value, d);
28093
+ return d;
28094
+ }
28095
+ if (value instanceof RegExp) {
28096
+ const r = new RegExp(value.source, value.flags);
28097
+ seen.set(value, r);
28098
+ return r;
28099
+ }
28100
+ if (value instanceof Map) {
28101
+ const out = /* @__PURE__ */ new Map();
28102
+ seen.set(value, out);
28103
+ for (const [k, v] of value) out.set(cloneValue(k, seen), cloneValue(v, seen));
28104
+ return out;
28105
+ }
28106
+ if (value instanceof Set) {
28107
+ const out = /* @__PURE__ */ new Set();
28108
+ seen.set(value, out);
28109
+ for (const v of value) out.add(cloneValue(v, seen));
28110
+ return out;
28111
+ }
28112
+ if (Array.isArray(value)) {
28113
+ const out = [];
28114
+ seen.set(value, out);
28115
+ for (const item of value) out.push(cloneValue(item, seen));
28116
+ return out;
28117
+ }
28118
+ if (ArrayBuffer.isView(value)) {
28119
+ const out = value.slice();
28120
+ seen.set(value, out);
28121
+ return out;
28122
+ }
28123
+ const proto = Object.getPrototypeOf(value);
28124
+ if (proto === Object.prototype || proto === null) {
28125
+ const out = {};
28126
+ seen.set(value, out);
28127
+ for (const key of Object.keys(value)) {
28128
+ out[key] = cloneValue(value[key], seen);
28129
+ }
28130
+ return out;
28131
+ }
28132
+ seen.set(value, value);
28133
+ try {
28134
+ return structuredClone(value);
28135
+ } catch {
28136
+ return value;
28137
+ }
28138
+ }
28139
+ function plainClone(value, seen) {
28140
+ if (value === null || typeof value !== "object") return value;
28141
+ seen = seen ?? /* @__PURE__ */ new Set();
28142
+ if (seen.has(value)) throw new Error("Path store: toJSON() cannot serialize cyclic state");
28143
+ seen.add(value);
28144
+ if (value instanceof Date) return value.toISOString();
28145
+ if (value instanceof RegExp) return String(value);
28146
+ if (value instanceof Map) {
28147
+ const out2 = [];
28148
+ for (const [k, v] of value) out2.push([plainClone(k, seen), plainClone(v, seen)]);
28149
+ return out2;
28150
+ }
28151
+ if (value instanceof Set) {
28152
+ const out2 = [];
28153
+ for (const v of value) out2.push(plainClone(v, seen));
28154
+ return out2;
28155
+ }
28156
+ if (Array.isArray(value)) {
28157
+ const out2 = [];
28158
+ for (const item of value) out2.push(plainClone(item, seen));
28159
+ return out2;
28160
+ }
28161
+ const out = {};
28162
+ for (const key of Object.keys(value)) {
28163
+ out[key] = plainClone(value[key], seen);
28164
+ }
28165
+ return out;
28166
+ }
28167
+ function shallowDiff(before, after, base, out) {
28168
+ if (Object.is(before, after)) return;
28169
+ const beforeObj = isObject2(before);
28170
+ const afterObj = isObject2(after);
28171
+ if (!beforeObj || !afterObj || Array.isArray(before) !== Array.isArray(after)) {
28172
+ out.push({ path: pathKey(base), before, after });
28173
+ return;
28174
+ }
28175
+ const array = Array.isArray(before);
28176
+ const keys = /* @__PURE__ */ new Set([
28177
+ ...Object.keys(before),
28178
+ ...Object.keys(after)
28179
+ ]);
28180
+ for (const key of keys) {
28181
+ const segment = array && isDigits(key) ? Number(key) : key;
28182
+ shallowDiff(
28183
+ before[key],
28184
+ after[key],
28185
+ [...base, segment],
28186
+ out
28187
+ );
28188
+ }
28189
+ }
28190
+ function createPathStore(initial, options = {}) {
28191
+ const { persist = false, storageKey, historyLimit = 500 } = options;
28192
+ let state = cloneValue(initial);
28193
+ if (persist && storageKey) {
28194
+ const raw2 = readPersistedStorage(storageKey);
28195
+ if (raw2) {
28196
+ try {
28197
+ const parsed = JSON.parse(raw2);
28198
+ if (parsed !== null && typeof parsed === "object") {
28199
+ state = { ...state, ...cloneValue(parsed) };
28200
+ }
28201
+ } catch {
28202
+ }
28203
+ }
28204
+ }
28205
+ const rootCell = track(state);
28206
+ const cellRoot = {};
28207
+ function nodeFor(path, create) {
28208
+ let node = cellRoot;
28209
+ for (const seg of path) {
28210
+ const key = String(seg);
28211
+ let child = node.children?.get(key);
28212
+ if (!child) {
28213
+ if (!create) return null;
28214
+ child = {};
28215
+ if (!node.children) node.children = /* @__PURE__ */ new Map();
28216
+ node.children.set(key, child);
28217
+ }
28218
+ node = child;
28219
+ }
28220
+ return node;
28221
+ }
28222
+ function cellFor(path) {
28223
+ const node = nodeFor(path, true);
28224
+ if (!node.cell) {
28225
+ node.cell = track(getIn(state, path));
28226
+ setImprint(node, path);
28227
+ }
28228
+ return node.cell;
28229
+ }
28230
+ function collectCellNodes(node) {
28231
+ const out = [];
28232
+ if (!node) return out;
28233
+ const stack = [node];
28234
+ while (stack.length > 0) {
28235
+ const n = stack.pop();
28236
+ if (n.cell) out.push(n);
28237
+ if (n.children) for (const child of n.children.values()) stack.push(child);
28238
+ }
28239
+ return out;
28240
+ }
28241
+ function cellsRelatedTo(path) {
28242
+ const out = [];
28243
+ const tNode = nodeFor(path, false);
28244
+ out.push(...collectCellNodes(tNode));
28245
+ for (let i = path.length - 1; i > 0; i--) {
28246
+ const ancestor = nodeFor(path.slice(0, i), false);
28247
+ if (ancestor?.cell) out.push(ancestor);
28248
+ }
28249
+ return out;
28250
+ }
28251
+ function syncCell(node, path) {
28252
+ const cell = node.cell;
28253
+ const next = getIn(state, path);
28254
+ if (!Object.is(cell.get(), next)) cell.set(next);
28255
+ }
28256
+ function syncPathCells(touched) {
28257
+ if (touched === null) {
28258
+ for (const node of collectCellNodes(cellRoot)) {
28259
+ if (node.cell) syncCell(node, nodePathOf(node));
28260
+ }
28261
+ return;
28262
+ }
28263
+ for (const node of cellsRelatedTo(touched)) {
28264
+ if (!node.cell) continue;
28265
+ syncCell(node, nodePathOf(node));
28266
+ }
28267
+ }
28268
+ function nodePathOf(node) {
28269
+ return nodePathCache.get(node) ?? [];
28270
+ }
28271
+ const nodePathCache = /* @__PURE__ */ new Map();
28272
+ function setImprint(node, path) {
28273
+ nodePathCache.set(node, path.slice());
28274
+ }
28275
+ const derivedDefs = /* @__PURE__ */ new Map();
28276
+ const depRoot = { defs: null };
28277
+ function depNodeFor(tokens, create) {
28278
+ let node = depRoot;
28279
+ for (const seg of tokens) {
28280
+ const key = String(seg);
28281
+ let child = node.children?.get(key);
28282
+ if (!child) {
28283
+ if (!create) return null;
28284
+ child = { defs: null };
28285
+ if (!node.children) node.children = /* @__PURE__ */ new Map();
28286
+ node.children.set(key, child);
28287
+ }
28288
+ node = child;
28289
+ }
28290
+ return node;
28291
+ }
28292
+ function registerDep(def, tokens) {
28293
+ const node = depNodeFor(tokens, true);
28294
+ if (!node.defs) node.defs = /* @__PURE__ */ new Set();
28295
+ node.defs.add(def);
28296
+ }
28297
+ function unregisterDep(def, tokens) {
28298
+ const node = depNodeFor(tokens, false);
28299
+ if (node?.defs) {
28300
+ node.defs.delete(def);
28301
+ if (node.defs.size === 0) node.defs = null;
28302
+ }
28303
+ }
28304
+ function registerDef(def) {
28305
+ for (const dep of def.deps) registerDep(def, dep);
28306
+ }
28307
+ function unregisterDef(def) {
28308
+ for (const dep of def.deps) unregisterDep(def, dep);
28309
+ }
28310
+ function derivedsRelatedTo(path, out) {
28311
+ const n = depNodeFor(path, false);
28312
+ if (n) {
28313
+ const stack = [n];
28314
+ while (stack.length > 0) {
28315
+ const node = stack.pop();
28316
+ if (node.defs) for (const def of node.defs) out.add(def);
28317
+ if (node.children) for (const child of node.children.values()) stack.push(child);
28318
+ }
28319
+ }
28320
+ for (let i = path.length - 1; i > 0; i--) {
28321
+ const ancestor = depNodeFor(path.slice(0, i), false);
28322
+ if (ancestor?.defs) for (const def of ancestor.defs) out.add(def);
28323
+ }
28324
+ return Array.from(out);
28325
+ }
28326
+ const COLLAPSE_THRESHOLD = 8;
28327
+ const proxyTargets = /* @__PURE__ */ new WeakMap();
28328
+ function evaluate(selector) {
28329
+ return untrack2(() => {
28330
+ const deps = [];
28331
+ const seen = /* @__PURE__ */ new Set();
28332
+ const envelopeLeaves = /* @__PURE__ */ new Map();
28333
+ const collapsed = /* @__PURE__ */ new Set();
28334
+ const recordLeaf = (path) => {
28335
+ const k = pathKey(path);
28336
+ if (!seen.has(k)) {
28337
+ seen.add(k);
28338
+ deps.push(path);
28339
+ }
28340
+ };
28341
+ const recordEnvelope = (env) => {
28342
+ if (env.length === 0) return;
28343
+ const k = pathKey(env);
28344
+ const count = (envelopeLeaves.get(k) ?? 0) + 1;
28345
+ envelopeLeaves.set(k, count);
28346
+ if (count >= COLLAPSE_THRESHOLD) collapsed.add(k);
28347
+ recordLeaf(env);
28348
+ };
28349
+ const isPlain = (value) => value !== null && typeof value === "object" && (Array.isArray(value) || Object.prototype.toString.call(value) === "[object Object]");
28350
+ const wrap = (value, base) => {
28351
+ if (!isPlain(value)) return value;
28352
+ const proxy = new Proxy(value, {
28353
+ get(target, prop, receiver) {
28354
+ if (typeof prop === "symbol") return Reflect.get(target, prop, receiver);
28355
+ const array = Array.isArray(target);
28356
+ const segment = array && isDigits(String(prop)) ? Number(prop) : String(prop);
28357
+ const child = base.concat(segment);
28358
+ const v = Reflect.get(target, prop, receiver);
28359
+ if (isPlain(v)) return wrap(v, child);
28360
+ if (typeof v === "function") return v;
28361
+ recordLeaf(child);
28362
+ if (array) recordEnvelope(base);
28363
+ return v;
28364
+ },
28365
+ set() {
28366
+ throw new Error("Path store: derived selectors must be pure \u2014 no writes.");
28367
+ }
28368
+ });
28369
+ proxyTargets.set(proxy, value);
28370
+ return proxy;
28371
+ };
28372
+ const unwrap = (value) => {
28373
+ if (value === null || typeof value !== "object") return value;
28374
+ const target = proxyTargets.get(value);
28375
+ if (target !== void 0) return unwrap(target);
28376
+ if (Array.isArray(value)) {
28377
+ let changed2 = false;
28378
+ const out2 = [];
28379
+ for (const item of value) {
28380
+ const next = unwrap(item);
28381
+ if (next !== item) changed2 = true;
28382
+ out2.push(next);
28383
+ }
28384
+ return changed2 ? out2 : value;
28385
+ }
28386
+ let changed = false;
28387
+ const out = {};
28388
+ for (const key of Object.keys(value)) {
28389
+ const next = unwrap(value[key]);
28390
+ if (next !== value[key]) changed = true;
28391
+ out[key] = next;
28392
+ }
28393
+ return changed ? out : value;
28394
+ };
28395
+ const result = selector(wrap(state, []));
28396
+ const finalDeps = collapsed.size === 0 ? deps : deps.filter((d) => {
28397
+ for (const envKey of collapsed) {
28398
+ if (isStrictPrefix(tokensOfKey(envKey), d)) return false;
28399
+ }
28400
+ return true;
28401
+ });
28402
+ return { value: unwrap(result), deps: finalDeps };
28403
+ });
28404
+ }
28405
+ function recomputeDerived(changes, version3) {
28406
+ const queue = [];
28407
+ const queued = /* @__PURE__ */ new Set();
28408
+ const collect = (tokens) => {
28409
+ for (const def of derivedsRelatedTo(tokens, /* @__PURE__ */ new Set())) {
28410
+ if (!queued.has(def)) {
28411
+ queued.add(def);
28412
+ queue.push(def);
28413
+ }
28414
+ }
28415
+ };
28416
+ for (const change of changes) collect(tokensOfKey(change.path));
28417
+ while (queue.length > 0) {
28418
+ const def = queue.pop();
28419
+ unregisterDef(def);
28420
+ const { value, deps } = evaluate(def.selector);
28421
+ def.deps = deps;
28422
+ registerDef(def);
28423
+ const before = def.cell.get();
28424
+ if (!def.equals(before, value)) {
28425
+ def.cell.set(value);
28426
+ def.lastTrigger = changes.map((c) => tokensOfKey(c.path));
28427
+ def.lastTriggerVersion = version3;
28428
+ mergedDirty = true;
28429
+ const change = { path: def.path, before, after: value };
28430
+ changes.push(change);
28431
+ collect(def.tokens);
28432
+ }
28433
+ }
28434
+ }
28435
+ let mergedCache = null;
28436
+ let mergedDirty = true;
28437
+ function invalidateMerged() {
28438
+ mergedCache = null;
28439
+ mergedDirty = true;
28440
+ }
28441
+ function buildMerged() {
28442
+ if (!mergedDirty && mergedCache !== null) return mergedCache;
28443
+ const base = rootCell.get();
28444
+ if (derivedDefs.size === 0) {
28445
+ mergedCache = base;
28446
+ mergedDirty = false;
28447
+ return base;
28448
+ }
28449
+ let acc = base;
28450
+ for (const def of derivedDefs.values()) {
28451
+ acc = setIn(acc, def.tokens, def.cell.get());
28452
+ }
28453
+ mergedCache = acc;
28454
+ mergedDirty = false;
28455
+ return acc;
28456
+ }
28457
+ const events = [];
28458
+ let version2 = 0;
28459
+ let undoStack = [];
28460
+ let redoStack = [];
28461
+ const lastCause = /* @__PURE__ */ new Map();
28462
+ function recordCause(changes, action, atVersion) {
28463
+ for (const change of changes) {
28464
+ lastCause.set(change.path, { action, version: atVersion });
28465
+ }
28466
+ }
28467
+ function commit(next, action, touched) {
28468
+ untrack2(() => {
28469
+ if (Object.is(next, state)) return;
28470
+ const changes = [];
28471
+ if (touched !== null) {
28472
+ shallowDiff(getIn(state, touched), getIn(next, touched), touched, changes);
28473
+ } else {
28474
+ shallowDiff(state, next, [], changes);
28475
+ }
28476
+ if (changes.length === 0) return;
28477
+ undoStack.push(state);
28478
+ if (undoStack.length > historyLimit) undoStack.shift();
28479
+ redoStack = [];
28480
+ state = next;
28481
+ rootCell.set(state);
28482
+ invalidateMerged();
28483
+ const nextVersion = version2 + 1;
28484
+ recordCause(changes, action, nextVersion);
28485
+ recomputeDerived(changes, nextVersion);
28486
+ syncPathCells(touched);
28487
+ dispatchAll();
28488
+ persistToStorage();
28489
+ version2 = nextVersion;
28490
+ events.push({ version: version2, action, at: Date.now(), changes });
28491
+ if (events.length > historyLimit) events.shift();
28492
+ });
28493
+ }
28494
+ function restore(snapshot, action) {
28495
+ const changes = [];
28496
+ untrack2(() => {
28497
+ shallowDiff(state, snapshot, [], changes);
28498
+ state = snapshot;
28499
+ rootCell.set(state);
28500
+ invalidateMerged();
28501
+ const nextVersion = version2 + 1;
28502
+ recordCause(changes, action, nextVersion);
28503
+ recomputeDerived(changes, nextVersion);
28504
+ syncPathCells(null);
28505
+ if (changes.length > 0) dispatchAll();
28506
+ persistToStorage();
28507
+ version2 = nextVersion;
28508
+ events.push({ version: version2, action, at: Date.now(), changes });
28509
+ if (events.length > historyLimit) events.shift();
28510
+ });
28511
+ return changes;
28512
+ }
28513
+ function persistToStorage() {
28514
+ if (!persist || !storageKey) return;
28515
+ try {
28516
+ writePersistedStorage(storageKey, JSON.stringify(state));
28517
+ } catch {
28518
+ }
28519
+ }
28520
+ const subscribers = /* @__PURE__ */ new Set();
28521
+ const watchers = /* @__PURE__ */ new Set();
28522
+ function dispatchAll() {
28523
+ const current2 = buildMerged();
28524
+ for (const wrapper of subscribers) wrapper(current2);
28525
+ for (const wrapper of watchers) wrapper();
28526
+ }
28527
+ function whyAt(tokens, depth = 0, versionNow = version2) {
28528
+ const path = pathKey(tokens);
28529
+ const value = getIn(state, tokens);
28530
+ if (depth > 64) return { path, value, cause: "initial" };
28531
+ const def = derivedDefs.get(path);
28532
+ if (def) {
28533
+ const node = {
28534
+ path,
28535
+ value: def.cell.get(),
28536
+ cause: "derived",
28537
+ from: def.deps.map((dep) => whyAt(dep, depth + 1))
28538
+ };
28539
+ if (def.lastTrigger) {
28540
+ node.changedBy = def.lastTrigger.map((trigger, i) => ({
28541
+ path: pathKey(trigger),
28542
+ value: getIn(state, trigger),
28543
+ cause: "action",
28544
+ action: i === 0 ? void 0 : void 0,
28545
+ // filled below from events
28546
+ version: def.lastTriggerVersion
28547
+ }));
28548
+ const first = def.lastTrigger[0];
28549
+ const ev = events.slice().reverse().find((e) => e.changes.some((c) => c.path === pathKey(first)));
28550
+ if (ev) {
28551
+ node.changedBy[0].action = ev.action;
28552
+ node.changedBy[0].version = ev.version;
28553
+ node.version = ev.version;
28554
+ }
28555
+ }
28556
+ void versionNow;
28557
+ return node;
28558
+ }
28559
+ const cause = lastCause.get(path);
28560
+ if (cause) {
28561
+ if (cause.action === "undo" || cause.action === "redo") {
28562
+ return { path, value, cause: "time-travel", action: cause.action, version: cause.version };
28563
+ }
28564
+ return { path, value, cause: "action", action: cause.action, version: cause.version };
28565
+ }
28566
+ return { path, value, cause: "initial" };
28567
+ }
28568
+ function renderExplanation(node, indent4 = 0) {
28569
+ const pad = " ".repeat(indent4);
28570
+ const lines = [];
28571
+ const tag = node.cause === "derived" ? "derived" : node.cause === "action" ? `${node.action ?? "action"} \xB7 v${node.version ?? "?"}` : node.cause === "time-travel" ? `time-travel \xB7 v${node.version ?? "?"}` : "initial";
28572
+ lines.push(`${pad}${node.path} = ${JSON.stringify(node.value)} (${tag})`);
28573
+ if (node.changedBy && node.changedBy.length > 0) {
28574
+ lines.push(`${pad} recomputed after:`);
28575
+ for (const change of node.changedBy) {
28576
+ lines.push(renderExplanation({ ...change, from: void 0 }, indent4 + 2));
28577
+ }
28578
+ } else if (node.from && node.from.length > 0) {
28579
+ for (const child of node.from) lines.push(renderExplanation(child, indent4 + 1));
28580
+ }
28581
+ return lines.join("\n");
28582
+ }
28583
+ function derivedHandle(def, displayPath2) {
28584
+ return {
28585
+ path: def.path,
28586
+ get deps() {
28587
+ return def.deps.map((dep) => dep.join("."));
28588
+ },
28589
+ get() {
28590
+ return def.cell.get();
28591
+ },
28592
+ subscribe(cb) {
28593
+ let prev = def.cell.get();
28594
+ return store.subscribe(() => {
28595
+ const next = def.cell.get();
28596
+ if (!Object.is(prev, next)) {
28597
+ prev = next;
28598
+ cb(next);
28599
+ }
28600
+ });
28601
+ }
28602
+ };
28603
+ void displayPath2;
28604
+ }
28605
+ const store = {
28606
+ /** Reactive whole-state read — re-runs on any commit. Includes derived
28607
+ * values at their registered paths (derived wins over a raw key). */
28608
+ get() {
28609
+ rootCell.get();
28610
+ return buildMerged();
28611
+ },
28612
+ /** A fine-grained, causally-aware handle for one nested path. When a
28613
+ * derived is registered at this path, the handle reads/writes the
28614
+ * derived (set/update then throw read-only). */
28615
+ at(path) {
28616
+ const tokens = parseStorePath(path);
28617
+ const key = pathKey(tokens);
28618
+ const def = derivedDefs.get(key);
28619
+ if (def) {
28620
+ const handle2 = derivedHandle(def, path);
28621
+ return {
28622
+ path: key,
28623
+ get: handle2.get,
28624
+ set() {
28625
+ throw new Error(`Path store: derived path "${path}" is read-only.`);
28626
+ },
28627
+ update() {
28628
+ throw new Error(`Path store: derived path "${path}" is read-only.`);
28629
+ },
28630
+ subscribe: handle2.subscribe
28631
+ };
28632
+ }
28633
+ return {
28634
+ path: key,
28635
+ get() {
28636
+ return cellFor(tokens).get();
28637
+ },
28638
+ set(value, action = "set") {
28639
+ commit(setIn(state, tokens, cloneValue(value)), action, tokens);
28640
+ },
28641
+ update(fn, action = "update") {
28642
+ commit(updateIn(state, tokens, fn), action, tokens);
28643
+ },
28644
+ subscribe(cb) {
28645
+ let prev = cellFor(tokens).get();
28646
+ return store.subscribe(() => {
28647
+ const next = cellFor(tokens).get();
28648
+ if (!Object.is(prev, next)) {
28649
+ prev = next;
28650
+ cb(next);
28651
+ }
28652
+ });
28653
+ }
28654
+ };
28655
+ },
28656
+ /** Replace the whole state (attributed to `action`). */
28657
+ set(next, action = "set") {
28658
+ commit(cloneValue(next), action, null);
28659
+ },
28660
+ /** Shallow merge a partial (or `(prev) => partial`) into the root. */
28661
+ update(patch, action = "update") {
28662
+ const partial = typeof patch === "function" ? patch(state) : patch;
28663
+ commit({ ...state, ...cloneValue(partial) }, action, null);
28664
+ },
28665
+ setIn(path, value, action = "setIn") {
28666
+ const tokens = typeof path === "string" ? parseStorePath(path) : path;
28667
+ commit(setIn(state, tokens, cloneValue(value)), action, tokens);
28668
+ },
28669
+ updateIn(path, fn, action = "updateIn") {
28670
+ const tokens = typeof path === "string" ? parseStorePath(path) : path;
28671
+ commit(updateIn(state, tokens, fn), action, tokens);
28672
+ },
28673
+ /**
28674
+ * Register a derived node at `path`. The selector is evaluated inside
28675
+ * `untrack` against a read-recording proxy, so its source paths are
28676
+ * captured automatically — including array envelopes, which make
28677
+ * aggregate deriveds re-run when the array's membership changes.
28678
+ */
28679
+ derived(path, selector, equals = Object.is) {
28680
+ const tokens = parseStorePath(path);
28681
+ const key = pathKey(tokens);
28682
+ const first = evaluate(selector);
28683
+ const def = {
28684
+ path: key,
28685
+ tokens,
28686
+ selector,
28687
+ equals,
28688
+ cell: track(first.value),
28689
+ deps: first.deps,
28690
+ lastTrigger: null,
28691
+ lastTriggerVersion: 0
28692
+ };
28693
+ derivedDefs.set(key, def);
28694
+ registerDef(def);
28695
+ mergedDirty = true;
28696
+ return derivedHandle(def, path);
28697
+ },
28698
+ subscribe(fn, selector, equals) {
28699
+ const eq = equals ?? Object.is;
28700
+ let hasPrev = false;
28701
+ let prev;
28702
+ const wrapper = selector ? () => {
28703
+ const selected = selector(buildMerged());
28704
+ if (!hasPrev || !eq(selected, prev)) {
28705
+ hasPrev = true;
28706
+ prev = selected;
28707
+ fn(selected);
28708
+ }
28709
+ } : (current2) => fn(current2);
28710
+ subscribers.add(wrapper);
28711
+ wrapper(buildMerged());
28712
+ return () => {
28713
+ subscribers.delete(wrapper);
28714
+ };
28715
+ },
28716
+ watch(selector, callback) {
28717
+ let prev = selector(buildMerged());
28718
+ const wrapper = () => {
28719
+ const next = selector(buildMerged());
28720
+ if (!Object.is(prev, next)) {
28721
+ const old = prev;
28722
+ prev = next;
28723
+ callback(next, old);
28724
+ }
28725
+ };
28726
+ watchers.add(wrapper);
28727
+ return () => {
28728
+ watchers.delete(wrapper);
28729
+ };
28730
+ },
28731
+ /** Causal explanation for the current value at `path`. */
28732
+ why(path) {
28733
+ return whyAt(parseStorePath(path));
28734
+ },
28735
+ /** A printable causal chain for devtools / tests. */
28736
+ explain(path) {
28737
+ return renderExplanation(whyAt(parseStorePath(path)));
28738
+ },
28739
+ /** The recorded events, oldest first. */
28740
+ get events() {
28741
+ return events;
28742
+ },
28743
+ get version() {
28744
+ return version2;
28745
+ },
28746
+ canUndo() {
28747
+ return undoStack.length > 0;
28748
+ },
28749
+ canRedo() {
28750
+ return redoStack.length > 0;
28751
+ },
28752
+ undo() {
28753
+ const prev = undoStack.pop();
28754
+ if (prev === void 0) return false;
28755
+ redoStack.push(state);
28756
+ restore(prev, "undo");
28757
+ return true;
28758
+ },
28759
+ redo() {
28760
+ const next = redoStack.pop();
28761
+ if (next === void 0) return false;
28762
+ undoStack.push(state);
28763
+ restore(next, "redo");
28764
+ return true;
28765
+ },
28766
+ /** A JSON-safe snapshot of the current merged state. */
28767
+ toJSON() {
28768
+ return plainClone(buildMerged());
28769
+ }
28770
+ };
28771
+ return store;
28772
+ }
28773
+ var init_path_store = __esm({
28774
+ "../runtime/src/path-store.ts"() {
28775
+ "use strict";
28776
+ init_ripple_runtime();
28777
+ init_nested_update();
28778
+ init_store_persistence();
28779
+ }
28780
+ });
28781
+
27758
28782
  // ../runtime/src/index-server.ts
27759
28783
  var index_server_exports = {};
27760
28784
  __export(index_server_exports, {
@@ -27809,8 +28833,10 @@ __export(index_server_exports, {
27809
28833
  createContext: () => createContext,
27810
28834
  createFileRouter: () => createFileRouter,
27811
28835
  createLocals: () => createLocals,
28836
+ createPathStore: () => createPathStore,
27812
28837
  createResource: () => createResource,
27813
28838
  createRouter: () => createRouter,
28839
+ createStore: () => createStore,
27814
28840
  create_component_ctx: () => create_component_ctx,
27815
28841
  create_try_block: () => create_try_block,
27816
28842
  custom: () => custom,
@@ -27936,6 +28962,8 @@ var init_index_server = __esm({
27936
28962
  init_action();
27937
28963
  init_metadata();
27938
28964
  init_nested_update();
28965
+ init_store();
28966
+ init_path_store();
27939
28967
  }
27940
28968
  });
27941
28969
 
@@ -36153,16 +37181,21 @@ function __matchPath(pattern, pathname) {
36153
37181
  let pi = 0, pp = 0;
36154
37182
  const params = {};
36155
37183
  while (pi < pathParts.length && pp < patternParts.length) {
36156
- if (patternParts[pp].startsWith(':')) {
36157
- const name = patternParts[pp].slice(1);
36158
- params[name] = pathParts[pi];
37184
+ const seg = patternParts[pp];
37185
+ // A "*name" segment is a catch-all and absorbs the rest of the path.
37186
+ if (seg.startsWith('*')) { params[seg.slice(1)] = pathParts.slice(pi).join('/'); pi = pathParts.length; pp++; }
37187
+ else if (seg.startsWith(':')) {
37188
+ params[seg.slice(1)] = pathParts[pi];
36159
37189
  pi++; pp++;
36160
- } else if (patternParts[pp] === pathParts[pi]) {
37190
+ } else if (seg === pathParts[pi]) {
36161
37191
  pi++; pp++;
36162
37192
  } else {
36163
37193
  return null;
36164
37194
  }
36165
37195
  }
37196
+ // A trailing catch-all still matches an empty tail; the loop above exits as
37197
+ // soon as the URL is exhausted, so without this it was never reached.
37198
+ if (pp === patternParts.length - 1 && patternParts[pp].startsWith('*')) { params[patternParts[pp].slice(1)] = pathParts.slice(pi).join('/'); pp++; }
36166
37199
  if (pp === patternParts.length && pi === pathParts.length) return params;
36167
37200
  return null;
36168
37201
  }
@@ -50924,10 +51957,17 @@ async function buildTreeShakenRuntimeNow(runtimeDir, usedNames) {
50924
51957
  const missing = unique.filter((n) => !available.has(n));
50925
51958
  if (missing.length > 0) {
50926
51959
  console.error(`vesk: runtime names not exported \u2014 ${missing.join(", ")}; falling back to full runtime`);
51960
+ const full = await bundleRuntimeNames(runtimeDir, [...available]);
51961
+ if (full) return full;
50927
51962
  return buildRuntimeCode(runtimeDir);
50928
51963
  }
51964
+ return await bundleRuntimeNames(runtimeDir, unique, true) ?? buildRuntimeCode(runtimeDir);
51965
+ }
51966
+ async function bundleRuntimeNames(runtimeDir, names, strict = false) {
51967
+ if (names.length === 0) return null;
50929
51968
  const entry = runtimeTreeShakeEntry();
50930
51969
  const indexClient = esbuildPath(join7(runtimeDir, "index-client.js"));
51970
+ const unique = [...new Set(names)];
50931
51971
  try {
50932
51972
  try {
50933
51973
  mkdirSync3(dirname8(entry), { recursive: true });
@@ -50964,8 +52004,8 @@ const { ${unique.join(", ")} } = __veskRuntime;
50964
52004
  export { ${unique.join(", ")} };
50965
52005
  `;
50966
52006
  } catch (e) {
50967
- console.error("vesk: runtime tree-shake failed, falling back to full runtime:", e.message);
50968
- return buildRuntimeCode(runtimeDir);
52007
+ if (strict) console.error("vesk: runtime tree-shake failed, falling back to full runtime:", e.message);
52008
+ return null;
50969
52009
  } finally {
50970
52010
  try {
50971
52011
  unlinkSync3(entry);
@@ -51072,6 +52112,18 @@ if (typeof document !== 'undefined') __router.start();
51072
52112
  }
51073
52113
 
51074
52114
  // ../adapter/src/manifest.ts
52115
+ function specificityKey(path) {
52116
+ return path.split("/").filter(Boolean).map((seg) => seg.startsWith("*") ? "2" + seg : seg.startsWith(":") ? "1" + seg : "0" + seg);
52117
+ }
52118
+ function compareSpecificity(a, b) {
52119
+ const ka = specificityKey(a);
52120
+ const kb = specificityKey(b);
52121
+ const len = Math.min(ka.length, kb.length);
52122
+ for (let i = 0; i < len; i++) {
52123
+ if (ka[i] !== kb[i]) return ka[i] < kb[i] ? -1 : 1;
52124
+ }
52125
+ return kb.length - ka.length;
52126
+ }
51075
52127
  function generateManifest(routes, ssrRoutes, apiRoutes, staticRoutes, middlewareEnabled, actionMap, headExtra, eventsEnabled = false) {
51076
52128
  const routeEntries = [];
51077
52129
  for (const r of ssrRoutes) {
@@ -51086,15 +52138,23 @@ function generateManifest(routes, ssrRoutes, apiRoutes, staticRoutes, middleware
51086
52138
  if (r._isrTags) entry.tags = r._isrTags;
51087
52139
  routeEntries.push(entry);
51088
52140
  }
52141
+ const apiEntries = [];
51089
52142
  for (const r of apiRoutes) {
51090
52143
  const urlParts = r.fullPath.split("/").filter(Boolean);
51091
- const name = urlParts.map((s) => s.startsWith(":") ? s.slice(1) || "param" : s).join("_") || "index";
51092
- routeEntries.push({
51093
- path: `/api${r.fullPath}`,
52144
+ const parts = urlParts.map((s, i) => {
52145
+ const last = i === urlParts.length - 1;
52146
+ if (last && r.isCatchAll && s.startsWith(":")) return "*" + s.slice(1);
52147
+ return s;
52148
+ });
52149
+ const name = parts.map((s) => s.startsWith(":") || s.startsWith("*") ? s.slice(1) || "param" : s).join("_") || "index";
52150
+ apiEntries.push({
52151
+ path: parts.length ? `/api/${parts.join("/")}` : "/api",
51094
52152
  type: "api",
51095
52153
  function: `server/api/${name}.js`
51096
52154
  });
51097
52155
  }
52156
+ apiEntries.sort((a, b) => compareSpecificity(a.path, b.path));
52157
+ routeEntries.push(...apiEntries);
51098
52158
  const ssgEntries = [];
51099
52159
  for (const r of staticRoutes) {
51100
52160
  ssgEntries.push({
@@ -51423,18 +52483,27 @@ async function startProdServer(outDir, options) {
51423
52483
  let pi = 0, pp2 = 0;
51424
52484
  const params = {};
51425
52485
  while (pi < pathParts.length && pp2 < patternParts.length) {
51426
- if (patternParts[pp2].startsWith(":")) {
51427
- const name = patternParts[pp2].slice(1);
52486
+ const seg = patternParts[pp2];
52487
+ if (seg.startsWith("*")) {
52488
+ params[seg.slice(1)] = pathParts.slice(pi).join("/");
52489
+ pi = pathParts.length;
52490
+ pp2++;
52491
+ } else if (seg.startsWith(":")) {
52492
+ const name = seg.slice(1);
51428
52493
  params[name] = pathParts[pi];
51429
52494
  pi++;
51430
52495
  pp2++;
51431
- } else if (patternParts[pp2] === pathParts[pi]) {
52496
+ } else if (seg === pathParts[pi]) {
51432
52497
  pi++;
51433
52498
  pp2++;
51434
52499
  } else {
51435
52500
  return null;
51436
52501
  }
51437
52502
  }
52503
+ if (pp2 === patternParts.length - 1 && patternParts[pp2].startsWith("*")) {
52504
+ params[patternParts[pp2].slice(1)] = pathParts.slice(pi).join("/");
52505
+ pp2++;
52506
+ }
51438
52507
  if (pp2 === patternParts.length && pi === pathParts.length) return params;
51439
52508
  return null;
51440
52509
  }
@@ -55372,6 +56441,20 @@ function collectSources(tree) {
55372
56441
  walk9(tree);
55373
56442
  return map;
55374
56443
  }
56444
+ function segmentRank(node) {
56445
+ if (node.isGroup || node.fullPath === "/")
56446
+ return 0;
56447
+ if (node.isCatchAll)
56448
+ return 3;
56449
+ if (node.isDynamic)
56450
+ return 2;
56451
+ return 1;
56452
+ }
56453
+ function bySegmentPrecedence(nodes) {
56454
+ if (nodes.length < 2)
56455
+ return nodes;
56456
+ return nodes.map((node, index) => ({ node, index, rank: segmentRank(node) })).sort((a, b) => a.rank - b.rank || a.index - b.index).map((entry) => entry.node);
56457
+ }
55375
56458
  function matchUrl(tree, pathname) {
55376
56459
  const parts = pathname.split("/").filter(Boolean);
55377
56460
  const chain = [];
@@ -55387,7 +56470,7 @@ function matchUrl(tree, pathname) {
55387
56470
  chain.push(node);
55388
56471
  }
55389
56472
  function matchNodes(nodes, partIndex) {
55390
- for (const node of nodes) {
56473
+ for (const node of bySegmentPrecedence(nodes)) {
55391
56474
  if (node.isGroup) {
55392
56475
  const marker = chain.length;
55393
56476
  if (node.layout || node.page)
@@ -55560,6 +56643,20 @@ function scanApiDir(rootDir, dir, parentPath) {
55560
56643
  }
55561
56644
  return nodes;
55562
56645
  }
56646
+ function specificityRank(node) {
56647
+ if (node.fullPath === "/")
56648
+ return 0;
56649
+ if (node.isCatchAll)
56650
+ return 3;
56651
+ if (node.isDynamic)
56652
+ return 2;
56653
+ return 1;
56654
+ }
56655
+ function bySpecificity(nodes) {
56656
+ if (nodes.length < 2)
56657
+ return nodes;
56658
+ return nodes.map((node, index) => ({ node, index, rank: specificityRank(node) })).sort((a, b) => a.rank - b.rank || a.index - b.index).map((entry) => entry.node);
56659
+ }
55563
56660
  function matchApiUrl(tree, pathname) {
55564
56661
  let normalized = pathname.split("?")[0].split("#")[0];
55565
56662
  if (normalized === "/api") {
@@ -55569,31 +56666,40 @@ function matchApiUrl(tree, pathname) {
55569
56666
  }
55570
56667
  const parts = normalized.split("/").filter(Boolean);
55571
56668
  const params = {};
56669
+ function restoreParams(snapshot) {
56670
+ for (const key of Object.keys(params)) {
56671
+ if (!(key in snapshot))
56672
+ delete params[key];
56673
+ }
56674
+ for (const key of Object.keys(snapshot))
56675
+ params[key] = snapshot[key];
56676
+ }
55572
56677
  function matchNodes(nodes, partIndex) {
55573
- for (const node of nodes) {
56678
+ for (const node of bySpecificity(nodes)) {
55574
56679
  if (node.fullPath === "/") {
55575
56680
  if (partIndex >= parts.length && node.filePath)
55576
56681
  return node;
55577
56682
  return matchNodes(node.children, partIndex);
55578
56683
  }
55579
- if (partIndex >= parts.length) {
55580
- if (node.filePath)
55581
- return node;
55582
- continue;
55583
- }
55584
- const part = parts[partIndex];
56684
+ const part = partIndex < parts.length ? parts[partIndex] : void 0;
55585
56685
  if (node.isCatchAll) {
56686
+ if (!node.filePath)
56687
+ continue;
55586
56688
  const paramName = node.path.startsWith(":") ? node.path.slice(1) : node.path;
55587
56689
  params[paramName] = parts.slice(partIndex).map(decodeURIComponent).join("/");
55588
56690
  return node;
55589
56691
  }
56692
+ if (part === void 0)
56693
+ continue;
55590
56694
  if (node.isDynamic) {
55591
56695
  const paramName = node.path.startsWith(":") ? node.path.slice(1) : node.path;
55592
56696
  params[paramName] = decodeURIComponent(part);
55593
56697
  if (node.children.length > 0) {
56698
+ const snapshot = { ...params };
55594
56699
  const result = matchNodes(node.children, partIndex + 1);
55595
56700
  if (result)
55596
56701
  return result;
56702
+ restoreParams(snapshot);
55597
56703
  }
55598
56704
  if (node.filePath)
55599
56705
  return node;
@@ -55601,10 +56707,14 @@ function matchApiUrl(tree, pathname) {
55601
56707
  continue;
55602
56708
  }
55603
56709
  if (node.path === part) {
56710
+ if (partIndex + 1 >= parts.length && node.filePath)
56711
+ return node;
55604
56712
  if (node.children.length > 0) {
56713
+ const snapshot = { ...params };
55605
56714
  const result = matchNodes(node.children, partIndex + 1);
55606
56715
  if (result)
55607
56716
  return result;
56717
+ restoreParams(snapshot);
55608
56718
  }
55609
56719
  if (node.filePath)
55610
56720
  return node;
@@ -57367,10 +58477,19 @@ async function buildTreeShakenRuntimeNow2(runtimeDir, usedNames) {
57367
58477
  const missing = unique.filter((n) => !available.has(n));
57368
58478
  if (missing.length > 0) {
57369
58479
  console.error(`vesk: runtime names not exported \u2014 ${missing.join(", ")}; falling back to full runtime`);
58480
+ const full = await bundleRuntimeNames2(runtimeDir, [...available]);
58481
+ if (full)
58482
+ return full;
57370
58483
  return buildRuntimeCode2(runtimeDir);
57371
58484
  }
58485
+ return await bundleRuntimeNames2(runtimeDir, unique, true) ?? buildRuntimeCode2(runtimeDir);
58486
+ }
58487
+ async function bundleRuntimeNames2(runtimeDir, names, strict = false) {
58488
+ if (names.length === 0)
58489
+ return null;
57372
58490
  const entry = runtimeTreeShakeEntry2();
57373
58491
  const indexClient = esbuildPath2(join20(runtimeDir, "index-client.js"));
58492
+ const unique = [...new Set(names)];
57374
58493
  try {
57375
58494
  try {
57376
58495
  mkdirSync12(dirname18(entry), { recursive: true });
@@ -57407,8 +58526,9 @@ const { ${unique.join(", ")} } = __veskRuntime;
57407
58526
  export { ${unique.join(", ")} };
57408
58527
  `;
57409
58528
  } catch (e) {
57410
- console.error("vesk: runtime tree-shake failed, falling back to full runtime:", e.message);
57411
- return buildRuntimeCode2(runtimeDir);
58529
+ if (strict)
58530
+ console.error("vesk: runtime tree-shake failed, falling back to full runtime:", e.message);
58531
+ return null;
57412
58532
  } finally {
57413
58533
  try {
57414
58534
  unlinkSync4(entry);
@@ -65592,8 +66712,10 @@ __export(index_server_exports2, {
65592
66712
  createContext: () => createContext,
65593
66713
  createFileRouter: () => createFileRouter,
65594
66714
  createLocals: () => createLocals,
66715
+ createPathStore: () => createPathStore,
65595
66716
  createResource: () => createResource,
65596
66717
  createRouter: () => createRouter,
66718
+ createStore: () => createStore,
65597
66719
  create_component_ctx: () => create_component_ctx,
65598
66720
  create_try_block: () => create_try_block,
65599
66721
  custom: () => custom,
@@ -65716,6 +66838,8 @@ init_loading_indicator();
65716
66838
  init_action();
65717
66839
  init_metadata();
65718
66840
  init_nested_update();
66841
+ init_store();
66842
+ init_path_store();
65719
66843
 
65720
66844
  // src/index.ts
65721
66845
  var __filename2 = fileURLToPath9(import.meta.url);