okno 1.0.0-alpha.20 → 1.0.0-alpha.21

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 +1 @@
1
- {"version":3,"file":"wrap.d.ts","sourceRoot":"","sources":["../../src/runtime/wrap.ts"],"names":[],"mappings":"AAyGA;;;;;GAKG;AACH,wBAAgB,cAAc,CAC7B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAChD,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAMzB;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,GAAG,CA2L5E;AAoDD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAChC,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,EACvC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC9B,OAAO,CA4BT;AAiBD,MAAM,WAAW,mBAAmB;IACnC,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAA;IACnC,cAAc;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,8DAA8D;IAC9D,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;;kFAG8E;IAC9E,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAA;IACpC;;kEAE8D;IAC9D,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC/B;AAsGD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI,CA6DtE;AA6DD;2EAC2E;AAC3E,wBAAgB,mBAAmB,IAAI,IAAI,CAK1C"}
1
+ {"version":3,"file":"wrap.d.ts","sourceRoot":"","sources":["../../src/runtime/wrap.ts"],"names":[],"mappings":"AAyGA;;;;;GAKG;AACH,wBAAgB,cAAc,CAC7B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAChD,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAMzB;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,GAAG,CA2L5E;AAoDD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAChC,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,EACvC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC9B,OAAO,CA8BT;AAiBD,MAAM,WAAW,mBAAmB;IACnC,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAA;IACnC,cAAc;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,8DAA8D;IAC9D,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;;kFAG8E;IAC9E,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAA;IACpC;;kEAE8D;IAC9D,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC/B;AAsGD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI,CA6DtE;AA6DD;2EAC2E;AAC3E,wBAAgB,mBAAmB,IAAI,IAAI,CAK1C"}
@@ -1,13 +1,13 @@
1
1
  const y = /* @__PURE__ */ new Map();
2
- let b = !1;
3
- function E() {
2
+ let g = !1;
3
+ function T() {
4
4
  const t = globalThis;
5
- b || typeof t.document > "u" || (b = !0, t.document.addEventListener("okno:change", (r) => {
6
- const { path: i, value: c } = r.detail;
7
- y.get(i)?.forEach((n) => n(c));
5
+ g || typeof t.document > "u" || (g = !0, t.document.addEventListener("okno:change", (r) => {
6
+ const { path: i, value: s } = r.detail;
7
+ y.get(i)?.forEach((n) => n(s));
8
8
  }));
9
9
  }
10
- const j = /* @__PURE__ */ new Set([
10
+ const E = /* @__PURE__ */ new Set([
11
11
  "src",
12
12
  "href",
13
13
  "alt",
@@ -20,90 +20,90 @@ const j = /* @__PURE__ */ new Set([
20
20
  "name",
21
21
  "value"
22
22
  ]);
23
- function O(t) {
23
+ function j(t) {
24
24
  return t.replace(/[-_]+/g, " ").replace(/([a-z])([A-Z])/g, "$1 $2").trim().replace(/^./, (r) => r.toUpperCase());
25
25
  }
26
- function v(t, r = "") {
26
+ function b(t, r = "") {
27
27
  if (t == null) {
28
28
  if (!r) return "";
29
29
  const i = r.split(".").pop() ?? "";
30
- return !i || j.has(i) ? "" : O(i);
30
+ return !i || E.has(i) ? "" : j(i);
31
31
  }
32
32
  return typeof t != "object" ? String(t) : m(t) ? t.text ?? "" : "";
33
33
  }
34
- function w(t) {
34
+ function A(t) {
35
35
  return typeof t == "object" && t !== null && !Array.isArray(t) && "src" in t;
36
36
  }
37
37
  function m(t) {
38
38
  return typeof t == "object" && t !== null && !Array.isArray(t) && "url" in t && "text" in t && "external" in t;
39
39
  }
40
- function S(t, r) {
40
+ function k(t, r) {
41
41
  if (r === void 0) return t;
42
42
  if (t === null || typeof t != "object" || Array.isArray(t) || r === null || typeof r != "object" || Array.isArray(r))
43
43
  return r;
44
44
  const i = { ...t };
45
- for (const c of Object.keys(r))
46
- i[c] = S(t[c], r[c]);
45
+ for (const s of Object.keys(r))
46
+ i[s] = k(t[s], r[s]);
47
47
  return i;
48
48
  }
49
- function z(t, r) {
49
+ function q(t, r) {
50
50
  const i = { ...t };
51
- for (const c of Object.keys(r))
52
- i[c] = S(t, r[c]);
51
+ for (const s of Object.keys(r))
52
+ i[s] = k(t, r[s]);
53
53
  return i;
54
54
  }
55
- function _(t, r, i) {
56
- const c = { __raw: t, __path: r, __slot: i };
57
- return new Proxy(c, {
55
+ function p(t, r, i) {
56
+ const s = { __raw: t, __path: r, __slot: i };
57
+ return new Proxy(s, {
58
58
  get(n, e) {
59
59
  if (e === "data-okno") return n.__path;
60
60
  if (e === "slot") return { "data-okno-item": n.__slot ?? n.__path };
61
61
  if (e === Symbol.toPrimitive || e === "toString" || e === "valueOf")
62
- return () => v(n.__raw, n.__path);
62
+ return () => b(n.__raw, n.__path);
63
63
  if (e === Symbol.iterator) {
64
- const u = v(n.__raw, n.__path);
64
+ const f = b(n.__raw, n.__path);
65
65
  return function* () {
66
- yield u;
66
+ yield f;
67
67
  };
68
68
  }
69
69
  if (typeof e == "symbol") return;
70
70
  if (e === "toJSON") return () => n.__raw;
71
71
  if (e === "on")
72
- return (u) => {
73
- E();
74
- const s = n.__path;
75
- return y.has(s) || y.set(s, /* @__PURE__ */ new Set()), y.get(s).add(u), () => {
76
- y.get(s)?.delete(u), y.get(s)?.size === 0 && y.delete(s);
72
+ return (f) => {
73
+ T();
74
+ const c = n.__path;
75
+ return y.has(c) || y.set(c, /* @__PURE__ */ new Set()), y.get(c).add(f), () => {
76
+ y.get(c)?.delete(f), y.get(c)?.size === 0 && y.delete(c);
77
77
  };
78
78
  };
79
79
  if (e === "locale")
80
- return (u) => {
81
- const s = n.__raw;
82
- return u && s !== null && typeof s == "object" && !Array.isArray(s) && typeof s[u] == "object" && s[u] !== null ? _(
83
- s[u],
80
+ return (f) => {
81
+ const c = n.__raw;
82
+ return f && c !== null && typeof c == "object" && !Array.isArray(c) && typeof c[f] == "object" && c[f] !== null ? p(
83
+ c[f],
84
84
  n.__path
85
- ) : _(s, n.__path);
85
+ ) : p(c, n.__path);
86
86
  };
87
- const o = n.__raw, f = n.__path ? `${n.__path}.${String(e)}` : String(e);
87
+ const o = n.__raw, a = n.__path ? `${n.__path}.${String(e)}` : String(e);
88
88
  if (m(o) && typeof e == "string") {
89
89
  if (e === "href") return o.url ?? "";
90
90
  if (e === "target" && o.external) return "_blank";
91
91
  if (e === "rel" && o.external) return "noopener noreferrer";
92
92
  }
93
93
  if (o != null && typeof o != "object") {
94
- const u = o[e];
95
- return u !== void 0 ? typeof u == "function" ? (...s) => u.apply(o, s) : u : _(null, f);
94
+ const f = o[e];
95
+ return f !== void 0 ? typeof f == "function" ? (...c) => f.apply(o, c) : f : p(null, a);
96
96
  }
97
97
  if (o != null && typeof o == "object" && !Array.isArray(o)) {
98
- const u = o[String(e)];
99
- return u == null ? _(null, f) : T(u, f);
98
+ const f = o[String(e)];
99
+ return f == null ? p(null, a) : $(f, a);
100
100
  }
101
- return _(null, f);
101
+ return p(null, a);
102
102
  },
103
103
  // For spread: expose data-okno, plus all keys for file objects (src, alt, width, height, etc.)
104
104
  ownKeys(n) {
105
105
  const e = n.__raw;
106
- return w(e) ? [...Object.keys(e), "data-okno"] : m(e) ? e.external ? ["href", "target", "rel", "data-okno"] : ["href", "data-okno"] : ["data-okno"];
106
+ return A(e) ? [...Object.keys(e), "data-okno"] : m(e) ? e.external ? ["href", "target", "rel", "data-okno"] : ["href", "data-okno"] : ["data-okno"];
107
107
  },
108
108
  getOwnPropertyDescriptor(n, e) {
109
109
  if (e === "data-okno")
@@ -113,7 +113,7 @@ function _(t, r, i) {
113
113
  configurable: !0
114
114
  };
115
115
  const o = n.__raw;
116
- if (w(o) && typeof e == "string" && e in o)
116
+ if (A(o) && typeof e == "string" && e in o)
117
117
  return {
118
118
  value: o[e],
119
119
  enumerable: !0,
@@ -129,144 +129,146 @@ function _(t, r, i) {
129
129
  }
130
130
  });
131
131
  }
132
- function k(t) {
132
+ function w(t) {
133
133
  return t !== null && typeof t == "object" && !Array.isArray(t) && "__oknoRef" in t;
134
134
  }
135
- function T(t, r, i) {
136
- if (k(t)) {
137
- const { path: c, data: n } = t.__oknoRef;
138
- return _(n, c, i ?? c);
135
+ function $(t, r, i) {
136
+ if (w(t)) {
137
+ const { path: s, data: n } = t.__oknoRef;
138
+ return p(n, s, i ?? s);
139
139
  }
140
140
  if (Array.isArray(t)) {
141
- const c = t.map((n, e) => T(n, `${r}.${e}`, `${r}.${e}`));
142
- return Object.defineProperty(c, "toJSON", {
143
- value: () => t.map((n) => k(n) ? n.__oknoRef.data : n),
141
+ const s = t.map((n, e) => $(n, `${r}.${e}`, `${r}.${e}`));
142
+ return Object.defineProperty(s, "toJSON", {
143
+ value: () => t.map((n) => w(n) ? n.__oknoRef.data : n),
144
144
  enumerable: !1
145
- }), c;
145
+ }), s;
146
146
  }
147
- return _(t, r, i);
147
+ return p(t, r, i);
148
148
  }
149
- function B(t, r, i) {
149
+ function z(t, r, i) {
150
150
  if (!t || typeof t != "object" || Array.isArray(t) || !r) return t;
151
- const c = { ...t };
151
+ const s = { ...t };
152
152
  for (const n of Object.keys(r)) {
153
153
  const e = r[n];
154
154
  if (!e || e.type !== "reference" || typeof e.collection != "string") continue;
155
- const o = i?.[e.collection] ?? i?.[e.collection.replace(/-/g, "_")] ?? [], f = (s) => {
156
- if (typeof s != "string" || !s) return null;
157
- const a = o.find((g) => {
158
- const A = typeof g?.toJSON == "function" ? g.toJSON() : g;
159
- return A && typeof A == "object" && A.slug === s;
160
- });
161
- if (!a) return null;
162
- const l = typeof a.toJSON == "function" ? a.toJSON() : a;
163
- return { __oknoRef: { path: `${e.collection}.${s}`, data: l } };
164
- }, u = t[n];
165
- c[n] = Array.isArray(u) ? u.map(f).filter(Boolean) : f(u);
155
+ const o = i?.[e.collection] ?? i?.[e.collection.replace(/-/g, "_")] ?? [], a = /* @__PURE__ */ new Map();
156
+ for (const u of o) {
157
+ const l = typeof u?.toJSON == "function" ? u.toJSON() : u;
158
+ l && typeof l == "object" && typeof l.slug == "string" && a.set(l.slug, u);
159
+ }
160
+ const f = (u) => {
161
+ if (typeof u != "string" || !u) return null;
162
+ const l = a.get(u);
163
+ if (!l) return null;
164
+ const S = typeof l.toJSON == "function" ? l.toJSON() : l;
165
+ return { __oknoRef: { path: `${e.collection}.${u}`, data: S } };
166
+ }, c = t[n];
167
+ s[n] = Array.isArray(c) ? c.map(f).filter(Boolean) : f(c);
166
168
  }
167
- return c;
169
+ return s;
168
170
  }
169
- const p = "data-okno-item", h = "data-okno", x = [h, p];
170
- function d(t, r, i, c = x) {
171
+ const _ = "data-okno-item", h = "data-okno", O = [h, _];
172
+ function d(t, r, i, s = O) {
171
173
  if (r === i) return;
172
174
  const n = (e) => {
173
- for (const o of c) {
174
- const f = e.getAttribute(o);
175
- f != null && (f === r ? e.setAttribute(o, i) : f.startsWith(r + ".") && e.setAttribute(o, i + f.slice(r.length)));
175
+ for (const o of s) {
176
+ const a = e.getAttribute(o);
177
+ a != null && (a === r ? e.setAttribute(o, i) : a.startsWith(r + ".") && e.setAttribute(o, i + a.slice(r.length)));
176
178
  }
177
179
  };
178
180
  n(t);
179
- for (const e of c) t.querySelectorAll(`[${e}]`).forEach(n);
181
+ for (const e of s) t.querySelectorAll(`[${e}]`).forEach(n);
180
182
  }
181
- function L(t) {
183
+ function x(t) {
182
184
  if (typeof document > "u") return [];
183
185
  const r = new RegExp(`^${t.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\.(\\d+)$`), i = /* @__PURE__ */ new Map();
184
- document.querySelectorAll(`[${p}]`).forEach((n) => {
185
- const e = n.getAttribute(p);
186
+ document.querySelectorAll(`[${_}]`).forEach((n) => {
187
+ const e = n.getAttribute(_);
186
188
  if (!e || !r.test(e) || !n.parentElement || !(n instanceof HTMLElement)) return;
187
189
  const o = i.get(n.parentElement) ?? [];
188
190
  o.push(n), i.set(n.parentElement, o);
189
191
  });
190
- const c = (n) => Number(n.getAttribute(p).match(r)[1]);
192
+ const s = (n) => Number(n.getAttribute(_).match(r)[1]);
191
193
  return [...i.entries()].map(([n, e]) => ({
192
194
  parent: n,
193
- wrappers: e.sort((o, f) => c(o) - c(f))
195
+ wrappers: e.sort((o, a) => s(o) - s(a))
194
196
  }));
195
197
  }
196
- function N(t) {
198
+ function L(t) {
197
199
  t.querySelectorAll(`[${h}]`).forEach((r) => {
198
200
  r.children.length === 0 && (r.textContent = "");
199
201
  });
200
202
  }
201
- function R(t, r) {
203
+ function M(t, r) {
202
204
  t.querySelectorAll(`[${h}]`).forEach((i) => {
203
- const c = i.getAttribute(h);
204
- c && c in r && i.children.length === 0 && (i.textContent = r[c] ?? "");
205
+ const s = i.getAttribute(h);
206
+ s && s in r && i.children.length === 0 && (i.textContent = r[s] ?? "");
205
207
  });
206
208
  }
207
- function M() {
209
+ function N() {
208
210
  return typeof window < "u" && typeof window.matchMedia == "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
209
211
  }
210
- function C(t) {
212
+ function R(t) {
211
213
  const r = document;
212
- return typeof r.startViewTransition != "function" || M() ? (t(), Promise.resolve()) : r.startViewTransition(t).finished.catch(() => {
214
+ return typeof r.startViewTransition != "function" || N() ? (t(), Promise.resolve()) : r.startViewTransition(t).finished.catch(() => {
213
215
  });
214
216
  }
215
- let H = 0;
216
- function I(t) {
217
+ let C = 0;
218
+ function H(t) {
217
219
  if (typeof document > "u" || !t?.list || !t.op) return;
218
- const { list: r, op: i } = t, c = L(r);
219
- if (i === "insert" && c.every((a) => a.wrappers.length === 0) || c.length === 0) return;
220
- const n = [], e = (a) => {
221
- a.style.viewTransitionName = `okno-vt-${++H}`, n.push(a);
220
+ const { list: r, op: i } = t, s = x(r);
221
+ if (i === "insert" && s.every((u) => u.wrappers.length === 0) || s.length === 0) return;
222
+ const n = [], e = (u) => {
223
+ u.style.viewTransitionName = `okno-vt-${++C}`, n.push(u);
222
224
  };
223
- for (const a of c) for (const l of a.wrappers) e(l);
225
+ for (const u of s) for (const l of u.wrappers) e(l);
224
226
  const o = document.documentElement;
225
227
  o.classList.add("okno-vt-active");
226
- const f = document.getElementById("okno-shadow-root"), u = f instanceof HTMLElement ? f.style.cssText : null;
227
- f instanceof HTMLElement && (f.style.cssText = `${u};position:fixed;inset:0;pointer-events:none;view-transition-name:okno-editor`), C(() => {
228
- for (const a of c)
229
- i === "reorder" ? J(a, r, t.from, t.to) : i === "remove" ? V(a, r, t.index) : i === "insert" && q(a, r, t, e);
228
+ const a = document.getElementById("okno-shadow-root"), f = a instanceof HTMLElement ? a.style.cssText : null;
229
+ a instanceof HTMLElement && (a.style.cssText = `${f};position:fixed;inset:0;pointer-events:none;view-transition-name:okno-editor`), R(() => {
230
+ for (const u of s)
231
+ i === "reorder" ? I(u, r, t.from, t.to) : i === "remove" ? J(u, r, t.index) : i === "insert" && V(u, r, t, e);
230
232
  }).finally(() => {
231
- for (const a of n) a.style.viewTransitionName = "";
232
- o.classList.remove("okno-vt-active"), f instanceof HTMLElement && u !== null && (f.style.cssText = u);
233
+ for (const u of n) u.style.viewTransitionName = "";
234
+ o.classList.remove("okno-vt-active"), a instanceof HTMLElement && f !== null && (a.style.cssText = f);
233
235
  });
234
236
  }
235
- function J(t, r, i, c) {
237
+ function I(t, r, i, s) {
236
238
  const n = t.wrappers, e = n.length;
237
- if (i < 0 || i >= e || c < 0 || c >= e || i === c) return;
238
- const o = n.slice(), [f] = o.splice(i, 1);
239
- o.splice(c, 0, f);
240
- const u = o.map((a) => a.getAttribute(p));
241
- o.forEach((a, l) => d(a, u[l], `${r}.${l}`));
242
- const s = n[e - 1].nextSibling;
243
- for (const a of o) t.parent.insertBefore(a, s);
239
+ if (i < 0 || i >= e || s < 0 || s >= e || i === s) return;
240
+ const o = n.slice(), [a] = o.splice(i, 1);
241
+ o.splice(s, 0, a);
242
+ const f = o.map((u) => u.getAttribute(_));
243
+ o.forEach((u, l) => d(u, f[l], `${r}.${l}`));
244
+ const c = n[e - 1].nextSibling;
245
+ for (const u of o) t.parent.insertBefore(u, c);
244
246
  }
245
- function V(t, r, i) {
246
- const c = t.wrappers;
247
- if (!(i < 0 || i >= c.length)) {
248
- c[i].remove();
249
- for (let n = i + 1; n < c.length; n++) d(c[n], `${r}.${n}`, `${r}.${n - 1}`);
247
+ function J(t, r, i) {
248
+ const s = t.wrappers;
249
+ if (!(i < 0 || i >= s.length)) {
250
+ s[i].remove();
251
+ for (let n = i + 1; n < s.length; n++) d(s[n], `${r}.${n}`, `${r}.${n - 1}`);
250
252
  }
251
253
  }
252
- function q(t, r, i, c) {
254
+ function V(t, r, i, s) {
253
255
  const n = t.wrappers, e = n.length;
254
256
  if (e === 0) return;
255
- const o = Math.max(0, Math.min(i.index ?? e, e)), f = o < e ? o : e - 1, u = n[f].getAttribute(p), s = n[f].cloneNode(!0);
257
+ const o = Math.max(0, Math.min(i.index ?? e, e)), a = o < e ? o : e - 1, f = n[a].getAttribute(_), c = n[a].cloneNode(!0);
256
258
  for (let l = e - 1; l >= o; l--) d(n[l], `${r}.${l}`, `${r}.${l + 1}`);
257
- d(s, u, `${r}.${o}`), i.remap && d(s, i.remap.from, i.remap.to, [h]), i.values ? R(s, i.values) : N(s), s.style.viewTransitionName = "", c(s);
258
- const a = o < e ? n[o] : n[e - 1].nextSibling;
259
- t.parent.insertBefore(s, a);
259
+ d(c, f, `${r}.${o}`), i.remap && d(c, i.remap.from, i.remap.to, [h]), i.values ? M(c, i.values) : L(c), c.style.viewTransitionName = "", s(c);
260
+ const u = o < e ? n[o] : n[e - 1].nextSibling;
261
+ t.parent.insertBefore(c, u);
260
262
  }
261
- let $ = !1;
262
- function P() {
263
+ let v = !1;
264
+ function B() {
263
265
  const t = globalThis;
264
- $ || typeof t.document > "u" || ($ = !0, t.document.addEventListener("okno:structure", (r) => I(r.detail)));
266
+ v || typeof t.document > "u" || (v = !0, t.document.addEventListener("okno:structure", (r) => H(r.detail)));
265
267
  }
266
268
  export {
267
- I as __oknoApplyStructure,
268
- P as __oknoInitStructure,
269
- z as __oknoLocalize,
270
- B as __oknoResolveRefs,
271
- _ as __oknoWrap
269
+ H as __oknoApplyStructure,
270
+ B as __oknoInitStructure,
271
+ q as __oknoLocalize,
272
+ z as __oknoResolveRefs,
273
+ p as __oknoWrap
272
274
  };
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "okno",
3
3
  "description": "Git-backed CMS with live editing for any Vite framework",
4
4
  "author": "Gabriel Uhlíř",
5
- "version": "1.0.0-alpha.20",
5
+ "version": "1.0.0-alpha.21",
6
6
  "homepage": "https://okno.build",
7
7
  "type": "module",
8
8
  "types": "./dist/index.d.ts",
@@ -57,7 +57,7 @@
57
57
  "acorn": "^8.11.3",
58
58
  "bits-ui": "^2.18.0",
59
59
  "runed": "^0.23.0",
60
- "simple-git": "^3.28.0",
60
+ "simple-git": "^3.32.0",
61
61
  "svelte": "^5.55.0",
62
62
  "svelte-dnd-action": "^0.9.69"
63
63
  },
@@ -73,7 +73,7 @@
73
73
  "tailwindcss": "^4.0.0",
74
74
  "tailwindcss-animate": "^1.0.7",
75
75
  "typescript": "^5.9.2",
76
- "vite": "^6.4.1"
76
+ "vite": "^6.4.3"
77
77
  },
78
78
  "peerDependencies": {
79
79
  "svelte": "^5.0.0",
@@ -0,0 +1,82 @@
1
+ import { describe, expect, test } from "bun:test"
2
+ import { __oknoResolveRefs } from "./wrap"
3
+
4
+ describe("__oknoResolveRefs", () => {
5
+ test("single ref happy path", () => {
6
+ const raw = { author: "jane" }
7
+ const fields = { author: { type: "reference", collection: "authors" } }
8
+ const collections = { authors: [{ slug: "jane", name: "Jane" }] }
9
+ const result = __oknoResolveRefs(raw, fields, collections) as any
10
+ expect(result.author).toEqual({
11
+ __oknoRef: { path: "authors.jane", data: { slug: "jane", name: "Jane" } },
12
+ })
13
+ })
14
+
15
+ test("array refs with a missing id filtered out", () => {
16
+ const raw = { authors: ["jane", "unknown"] }
17
+ const fields = { authors: { type: "reference", collection: "authors" } }
18
+ const collections = { authors: [{ slug: "jane", name: "Jane" }] }
19
+ const result = __oknoResolveRefs(raw, fields, collections) as any
20
+ expect(result.authors).toHaveLength(1)
21
+ expect(result.authors[0].__oknoRef.path).toBe("authors.jane")
22
+ })
23
+
24
+ test("item with toJSON method — data is toJSON output, match by toJSON slug", () => {
25
+ const item = {
26
+ _raw: { slug: "bob", name: "Bob" },
27
+ toJSON() {
28
+ return this._raw
29
+ },
30
+ }
31
+ const raw = { author: "bob" }
32
+ const fields = { author: { type: "reference", collection: "people" } }
33
+ const collections = { people: [item] }
34
+ const result = __oknoResolveRefs(raw, fields, collections) as any
35
+ expect(result.author.__oknoRef.data).toEqual({ slug: "bob", name: "Bob" })
36
+ expect(result.author.__oknoRef.path).toBe("people.bob")
37
+ })
38
+
39
+ test("dash/underscore fallback — def.collection dashed, collections key underscored", () => {
40
+ const raw = { post: "hello" }
41
+ const fields = { post: { type: "reference", collection: "blog-posts" } }
42
+ const collections = { blog_posts: [{ slug: "hello", title: "Hello World" }] }
43
+ const result = __oknoResolveRefs(raw, fields, collections) as any
44
+ expect(result.post.__oknoRef.path).toBe("blog-posts.hello")
45
+ expect(result.post.__oknoRef.data).toEqual({ slug: "hello", title: "Hello World" })
46
+ })
47
+
48
+ test("non-reference field passes through untouched", () => {
49
+ const raw = { title: "Hello", author: "jane" }
50
+ const fields = {
51
+ title: { type: "text" },
52
+ author: { type: "reference", collection: "authors" },
53
+ }
54
+ const collections = { authors: [{ slug: "jane", name: "Jane" }] }
55
+ const result = __oknoResolveRefs(raw, fields, collections) as any
56
+ expect(result.title).toBe("Hello")
57
+ })
58
+
59
+ test("null id returns null (single ref)", () => {
60
+ const raw = { author: null }
61
+ const fields = { author: { type: "reference", collection: "authors" } }
62
+ const collections = { authors: [{ slug: "jane", name: "Jane" }] }
63
+ const result = __oknoResolveRefs(raw, fields, collections) as any
64
+ expect(result.author).toBeNull()
65
+ })
66
+
67
+ test("empty string id returns null", () => {
68
+ const raw = { author: "" }
69
+ const fields = { author: { type: "reference", collection: "authors" } }
70
+ const collections = { authors: [{ slug: "jane", name: "Jane" }] }
71
+ const result = __oknoResolveRefs(raw, fields, collections) as any
72
+ expect(result.author).toBeNull()
73
+ })
74
+
75
+ test("unknown id returns null (single ref)", () => {
76
+ const raw = { author: "nobody" }
77
+ const fields = { author: { type: "reference", collection: "authors" } }
78
+ const collections = { authors: [{ slug: "jane", name: "Jane" }] }
79
+ const result = __oknoResolveRefs(raw, fields, collections) as any
80
+ expect(result.author).toBeNull()
81
+ })
82
+ })
@@ -392,12 +392,14 @@ export function __oknoResolveRefs(
392
392
  const list: any[] =
393
393
  collections?.[def.collection] ?? collections?.[def.collection.replace(/-/g, "_")] ?? []
394
394
 
395
+ const bySlug = new Map<string, any>()
396
+ for (const it of list) {
397
+ const r = typeof it?.toJSON === "function" ? it.toJSON() : it
398
+ if (r && typeof r === "object" && typeof r.slug === "string") bySlug.set(r.slug, it)
399
+ }
395
400
  const resolve = (id: unknown): OknoRef | null => {
396
401
  if (typeof id !== "string" || !id) return null
397
- const item = list.find((it) => {
398
- const r = typeof it?.toJSON === "function" ? it.toJSON() : it
399
- return r && typeof r === "object" && r.slug === id
400
- })
402
+ const item = bySlug.get(id)
401
403
  if (!item) return null
402
404
  const data = typeof item.toJSON === "function" ? item.toJSON() : item
403
405
  return { __oknoRef: { path: `${def.collection}.${id}`, data } }