wrec 0.24.0 → 0.24.2

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.
@@ -22,7 +22,7 @@ declare type PropertyConfig = {
22
22
  dispatch?: boolean;
23
23
  required?: boolean;
24
24
  type: AnyClass;
25
- usedBy?: string[];
25
+ usedBy?: string | string[];
26
26
  value?: any;
27
27
  values?: string[];
28
28
  };
package/dist/wrec.d.ts CHANGED
@@ -22,7 +22,7 @@ declare type PropertyConfig = {
22
22
  dispatch?: boolean;
23
23
  required?: boolean;
24
24
  type: AnyClass;
25
- usedBy?: string[];
25
+ usedBy?: string | string[];
26
26
  value?: any;
27
27
  values?: string[];
28
28
  };
package/dist/wrec.es.js CHANGED
@@ -4,7 +4,7 @@ var D = (r) => {
4
4
  var N = (r, t, e) => t.has(r) || D("Cannot " + e);
5
5
  var p = (r, t, e) => (N(r, t, "read from private field"), e ? e.call(r) : t.get(r)), b = (r, t, e) => t.has(r) ? D("Cannot add the same private member more than once") : t instanceof WeakSet ? t.add(r) : t.set(r, e), E = (r, t, e, s) => (N(r, t, "write to private field"), s ? s.call(r, e) : t.set(r, e), e), V = (r, t, e) => (N(r, t, "access private method"), e);
6
6
  import W from "xss";
7
- function Z(r, t, e = "") {
7
+ function Y(r, t, e = "") {
8
8
  const s = /* @__PURE__ */ new WeakMap(), i = {
9
9
  // Intercept property reads.
10
10
  // This creates nested proxies lazily.
@@ -13,7 +13,7 @@ function Z(r, t, e = "") {
13
13
  if (c === null || typeof c != "object") return c;
14
14
  const a = s.get(c);
15
15
  if (a) return a;
16
- const f = e ? `${e}.${n}` : n, h = Z(c, t, f);
16
+ const f = e ? `${e}.${n}` : n, h = Y(c, t, f);
17
17
  return s.set(c, h), h;
18
18
  },
19
19
  // Intercept property writes.
@@ -29,18 +29,18 @@ function Z(r, t, e = "") {
29
29
  };
30
30
  return new Proxy(r, i);
31
31
  }
32
- function Y(r) {
32
+ function G(r) {
33
33
  const t = {};
34
34
  for (const [e, s] of Object.entries(r)) {
35
35
  const i = typeof s == "object" && s !== null;
36
- t[e] = i ? Y(s) : s;
36
+ t[e] = i ? G(s) : s;
37
37
  }
38
38
  return t;
39
39
  }
40
40
  const P = typeof window < "u" && typeof window.document < "u";
41
41
  let z = class extends Error {
42
42
  };
43
- var w, R, m, x, C, y, O, G;
43
+ var w, R, m, x, C, g, O, Q;
44
44
  const T = class T {
45
45
  constructor(t, e, s) {
46
46
  b(this, O);
@@ -50,11 +50,11 @@ const T = class T {
50
50
  b(this, m, []);
51
51
  b(this, x);
52
52
  b(this, C);
53
- b(this, y);
53
+ b(this, g);
54
54
  if (!t) throw new z("name cannot be empty");
55
55
  if (p(T, w).has(t))
56
56
  throw new z(`WrecState with name "${t}" already exists`);
57
- if (E(this, x, t), E(this, C, e), E(this, y, Z({}, V(this, O, G).bind(this))), e && P) {
57
+ if (E(this, x, t), E(this, C, e), E(this, g, Y({}, V(this, O, Q).bind(this))), e && P) {
58
58
  const i = sessionStorage.getItem("wrec-state-" + t), o = i ? JSON.parse(i) : void 0;
59
59
  o && (s = o);
60
60
  }
@@ -98,12 +98,12 @@ const T = class T {
98
98
  Object.defineProperty(this, t, {
99
99
  enumerable: !0,
100
100
  get() {
101
- return p(this, y)[t];
101
+ return p(this, g)[t];
102
102
  },
103
103
  set(s) {
104
- p(this, y)[t] = s;
104
+ p(this, g)[t] = s;
105
105
  }
106
- }), p(this, y)[t] = e;
106
+ }), p(this, g)[t] = e;
107
107
  }
108
108
  get id() {
109
109
  return p(this, R);
@@ -112,14 +112,14 @@ const T = class T {
112
112
  // For example: state.log()
113
113
  log() {
114
114
  console.log("WrecState:", p(this, x));
115
- for (const [t, e] of Object.entries(p(this, y)))
115
+ for (const [t, e] of Object.entries(p(this, g)))
116
116
  console.log(` ${t} = ${JSON.stringify(e)}`);
117
117
  }
118
118
  removeListener(t) {
119
119
  E(this, m, p(this, m).filter((e) => e.listenerRef.deref() !== t));
120
120
  }
121
121
  };
122
- w = new WeakMap(), R = new WeakMap(), m = new WeakMap(), x = new WeakMap(), C = new WeakMap(), y = new WeakMap(), O = new WeakSet(), G = function(t, e, s) {
122
+ w = new WeakMap(), R = new WeakMap(), m = new WeakMap(), x = new WeakMap(), C = new WeakMap(), g = new WeakMap(), O = new WeakSet(), Q = function(t, e, s) {
123
123
  const i = /* @__PURE__ */ new Set();
124
124
  for (const o of p(this, m)) {
125
125
  const n = o.listenerRef.deref();
@@ -144,7 +144,7 @@ w = new WeakMap(), R = new WeakMap(), m = new WeakMap(), x = new WeakMap(), C =
144
144
  }, b(T, w, /* @__PURE__ */ new Map()), P && window.addEventListener("beforeunload", () => {
145
145
  for (const [t, e] of p(T, w).entries())
146
146
  if (p(e, C)) {
147
- const s = Y(e);
147
+ const s = G(e);
148
148
  sessionStorage.setItem("wrec-state-" + t, JSON.stringify(s));
149
149
  }
150
150
  });
@@ -156,19 +156,19 @@ function q(r, t) {
156
156
  e = e[s];
157
157
  return e;
158
158
  }
159
- function it(r, t, e) {
159
+ function nt(r, t, e) {
160
160
  const s = t.split("."), i = s.length - 1;
161
161
  let o = r;
162
162
  s.forEach((n, c) => {
163
163
  c === i ? o[n] = e : o = o[n];
164
164
  });
165
165
  }
166
- const nt = /* @__PURE__ */ new Set(["button", "input", "label", "option", "th"]), J = "__WREC", X = "__";
167
- function rt(r) {
166
+ const rt = /* @__PURE__ */ new Set(["button", "input", "label", "option", "th"]), J = "__WREC", X = "__";
167
+ function ct(r) {
168
168
  const t = {
169
169
  allowCommentTag: !0,
170
170
  onTag: (i, o) => {
171
- if (nt.has(i)) return o;
171
+ if (rt.has(i)) return o;
172
172
  },
173
173
  onTagAttr(i, o, n) {
174
174
  if (o.startsWith("on")) return "";
@@ -199,14 +199,14 @@ function rt(r) {
199
199
  s = s.replace(n, i);
200
200
  }), s;
201
201
  }
202
- const ct = /* @__PURE__ */ new Set([
202
+ const at = /* @__PURE__ */ new Set([
203
203
  "class",
204
204
  "disabled",
205
205
  "hidden",
206
206
  "id",
207
207
  "tabindex",
208
208
  "title"
209
- ]), at = globalThis.HTMLElement ?? class {
209
+ ]), ft = globalThis.HTMLElement ?? class {
210
210
  }, F = globalThis.customElements ?? {
211
211
  get: (r) => {
212
212
  },
@@ -219,20 +219,20 @@ const ct = /* @__PURE__ */ new Set([
219
219
  new Error("customElements is not available in this environment")
220
220
  )
221
221
  };
222
- class g extends Error {
222
+ class y extends Error {
223
223
  }
224
- const ft = /([a-zA-Z-]+)\s*:\s*([^;}]+)/g, Q = "a-zA-Z_$", ht = Q + "0-9", M = `[${Q}][${ht}]*`, K = new RegExp(`this\\.(${M})\\s*\\(`, "g"), lt = /<!--\s*(.*?)\s*-->/, pt = /<(\w+)(?:\s[^>]*)?>((?:[^<]|<(?!\w))*?)<\/\1>/g, L = new RegExp(`^this\\.${M}$`), j = new RegExp(`this\\.${M}(\\.${M})*`, "g"), tt = new RegExp(`this\\.${M}(\\.${M})*`), ut = 5;
225
- function dt(r) {
224
+ const ht = /([a-zA-Z-]+)\s*:\s*([^;}]+)/g, tt = "a-zA-Z_$", lt = tt + "0-9", M = `[${tt}][${lt}]*`, K = new RegExp(`this\\.(${M})\\s*\\(`, "g"), pt = /<!--\s*(.*?)\s*-->/, ut = /<(\w+)(?:\s[^>]*)?>((?:[^<]|<(?!\w))*?)<\/\1>/g, L = new RegExp(`^this\\.${M}$`), j = new RegExp(`this\\.${M}(\\.${M})*`, "g"), et = new RegExp(`this\\.${M}(\\.${M})*`), dt = 5;
225
+ function mt(r) {
226
226
  return r instanceof HTMLButtonElement || r instanceof HTMLFieldSetElement || r instanceof HTMLInputElement || r instanceof HTMLSelectElement || r instanceof HTMLTextAreaElement || r instanceof d;
227
227
  }
228
- function Tt(r, t, e) {
228
+ function Mt(r, t, e) {
229
229
  const s = document.createElement(r);
230
230
  if (t)
231
231
  for (const [i, o] of Object.entries(t))
232
232
  s.setAttribute(i, o);
233
233
  return e && (s.innerHTML = e), s;
234
234
  }
235
- const U = (r) => Array.isArray(r.values) && r.values.length > 0 ? r.values[0] : mt(r.type), mt = (r) => r === String ? "" : r === Number ? 0 : r === Boolean ? !1 : r === Array ? [] : r === Object ? {} : void 0;
235
+ const U = (r) => Array.isArray(r.values) && r.values.length > 0 ? r.values[0] : bt(r.type), bt = (r) => r === String ? "" : r === Number ? 0 : r === Boolean ? !1 : r === Array ? [] : r === Object ? {} : void 0;
236
236
  function $(r) {
237
237
  const t = [];
238
238
  let e = r.firstElementChild;
@@ -240,8 +240,8 @@ function $(r) {
240
240
  t.push(e), e.shadowRoot && t.push(...$(e.shadowRoot)), e.firstElementChild && t.push(...$(e)), e = e.nextElementSibling;
241
241
  return t;
242
242
  }
243
- const A = (r) => r.substring(ut).split(".")[0];
244
- function et(r, t) {
243
+ const A = (r) => r.substring(dt).split(".")[0];
244
+ function st(r, t) {
245
245
  let e = r[0];
246
246
  return t.forEach((s, i) => {
247
247
  e += s + r[i + 1];
@@ -258,16 +258,16 @@ function B(r) {
258
258
  const { localName: t } = r;
259
259
  return t === "input" || t === "select";
260
260
  }
261
- const bt = (r) => r.replace(/<!--[\s\S]*?-->/g, "");
262
- function st(r, t, e, s) {
261
+ const yt = (r) => r.replace(/<!--[\s\S]*?-->/g, "");
262
+ function ot(r, t, e, s) {
263
263
  return r.slice(0, t) + s + r.slice(t + e);
264
264
  }
265
265
  function H(r) {
266
266
  const t = Number(r);
267
- if (isNaN(t)) throw new g(`can't convert "${r}" to a number`);
267
+ if (isNaN(t)) throw new y(`can't convert "${r}" to a number`);
268
268
  return t;
269
269
  }
270
- function ot(r, t, e) {
270
+ function it(r, t, e) {
271
271
  const [s, i] = t.split(":");
272
272
  if (I(e))
273
273
  if (typeof e == "boolean") {
@@ -285,8 +285,9 @@ function ot(r, t, e) {
285
285
  }
286
286
  function k(r, t, e) {
287
287
  const [s, i] = t.split(":");
288
- r instanceof CSSStyleRule ? r.style.setProperty(s, e) : (ot(r, s, e), s === "value" && B(r) && (r.value = e));
288
+ r instanceof CSSStyleRule ? r.style.setProperty(s, e) : (it(r, s, e), s === "value" && B(r) && (r.value = e));
289
289
  }
290
+ const Z = (r) => typeof r == "string" ? [r] : r;
290
291
  async function gt(r) {
291
292
  const t = /* @__PURE__ */ new Set();
292
293
  for (const s of $(r.content)) {
@@ -310,7 +311,7 @@ async function gt(r) {
310
311
  )
311
312
  );
312
313
  }
313
- class d extends at {
314
+ class d extends ft {
314
315
  // There is one instance of `attrToPropMap`, `properties`, `propToAttrMap`,
315
316
  // `propToComputedMap`, and `propToExprsMap` per Wrec subclass,
316
317
  // not one for only the Wrec class.
@@ -379,14 +380,14 @@ class d extends at {
379
380
  // to the properties of different parent components.
380
381
  // This is used to update a parent property
381
382
  // when the corresponding child property value changes.
382
- #g = /* @__PURE__ */ new Map();
383
+ #y = /* @__PURE__ */ new Map();
383
384
  // This is a map from component properties to state bindings.
384
385
  // It must be instance-specific because each component instance
385
386
  // can bind the same property to a different WrecState/path.
386
387
  #r = /* @__PURE__ */ new Map();
387
388
  static define(t) {
388
389
  if (this.elementName = t, F.get(t))
389
- throw new g(`custom element ${t} is already defined`);
390
+ throw new y(`custom element ${t} is already defined`);
390
391
  F.define(t, this);
391
392
  }
392
393
  constructor() {
@@ -449,7 +450,7 @@ class d extends at {
449
450
  this.css && (t += this.css), t += `</style>
450
451
  `;
451
452
  let e = this.html.trim();
452
- if (!e) throw new g("static property html must be set");
453
+ if (!e) throw new y("static property html must be set");
453
454
  return e.startsWith("<") || (e = `<span><!--${e}--></span>`), t + e;
454
455
  }
455
456
  changed(t, e, s) {
@@ -472,7 +473,7 @@ class d extends at {
472
473
  }
473
474
  #w(t, e, s) {
474
475
  if (t === "class" || t === "style")
475
- throw new g(`"${t}" is a reserved property`);
476
+ throw new y(`"${t}" is a reserved property`);
476
477
  const i = d.getAttrName(t), o = this.hasAttribute(i);
477
478
  e.required && !o && this.#e(this, i, "is a required attribute");
478
479
  let n = e.value;
@@ -493,7 +494,7 @@ class d extends at {
493
494
  if (h === l) return;
494
495
  this.#W(t, c, h), this[f] = h;
495
496
  const u = this.#r.get(t);
496
- u && it(u.state, u.stateProp, h), this.#_(t, c, h, i), this.#p || (this.#F(t), this.#x(t)), this.#I(t, h);
497
+ u && nt(u.state, u.stateProp, h), this.#_(t, c, h, i), this.#p || (this.#F(t), this.#x(t)), this.#I(t, h);
497
498
  const v = this.#d[t];
498
499
  v && this.setFormValue(v, String(h)), this.propertyChangedCallback(t, l, h), e.dispatch && this.dispatch("change", {
499
500
  tagName: this.localName,
@@ -507,12 +508,12 @@ class d extends at {
507
508
  #E() {
508
509
  const t = this.hasAttribute("disabled"), e = $(this.shadowRoot);
509
510
  for (const s of e)
510
- dt(s) && (s.disabled = t);
511
+ mt(s) && (s.disabled = t);
511
512
  }
512
513
  disconnectedCallback() {
513
514
  for (const { state: t } of this.#r.values())
514
515
  t.removeListener(this);
515
- this.#s.clear(), this.#m.clear(), this.#g.clear(), this.#r.clear();
516
+ this.#s.clear(), this.#m.clear(), this.#y.clear(), this.#r.clear();
516
517
  }
517
518
  dispatch(t, e) {
518
519
  this.dispatchEvent(
@@ -537,7 +538,7 @@ class d extends at {
537
538
  n === void 0 && this.#l(t, s, o);
538
539
  let [c, a] = s.split(":");
539
540
  const f = d.getPropName(c), h = this.#a(o);
540
- e && t.#a(f) || (t[f] = n), c === "value" && (a ? (t["on" + a] === void 0 && this.#e(t, s, "refers to an unsupported event name"), t.setAttribute(c, this[o])) : a = "change"), e && !h && t.#g.set(
541
+ e && t.#a(f) || (t[f] = n), c === "value" && (a ? (t["on" + a] === void 0 && this.#e(t, s, "refers to an unsupported event name"), t.setAttribute(c, this[o])) : a = "change"), e && !h && t.#y.set(
541
542
  d.getPropName(c),
542
543
  o
543
544
  );
@@ -591,7 +592,7 @@ class d extends at {
591
592
  let s = "";
592
593
  if (S(t)) {
593
594
  this.#h(t.textContent, t);
594
- const i = t.textContent?.match(lt);
595
+ const i = t.textContent?.match(pt);
595
596
  i && (s = i[1]);
596
597
  } else {
597
598
  const i = Array.from(t.childNodes).find(
@@ -716,11 +717,11 @@ class d extends at {
716
717
  for (const a of n.matchAll(K)) {
717
718
  const f = a[1];
718
719
  if (typeof this[f] != "function")
719
- throw new g(
720
+ throw new y(
720
721
  `property ${t} computed calls non-method ${f}`
721
722
  );
722
723
  for (const [h, l] of Object.entries(s.properties))
723
- l.usedBy?.includes(f) && o(h, n);
724
+ Z(l.usedBy)?.includes(f) && o(h, n);
724
725
  }
725
726
  }
726
727
  #f(t, e) {
@@ -735,7 +736,7 @@ class d extends at {
735
736
  // in attribute values or the text content of elements!
736
737
  #h(t, e, s = void 0) {
737
738
  if (!t) return;
738
- const i = this.#y(e, s, t);
739
+ const i = this.#g(e, s, t);
739
740
  if (!i) {
740
741
  const a = t.replaceAll("this..", "this.");
741
742
  s ? k(e, s, a) : "textContent" in e && (e.textContent = a);
@@ -771,11 +772,11 @@ class d extends at {
771
772
  !this.#i || !I(e) || (this.#i.set(t, e), this.#b?.setFormValue(this.#i));
772
773
  }
773
774
  static ssr(t = {}) {
774
- throw new g('Import Wrec from "wrec/ssr" to use the ssr method.');
775
+ throw new y('Import Wrec from "wrec/ssr" to use the ssr method.');
775
776
  }
776
777
  #e(t, e, s) {
777
778
  const i = t instanceof HTMLElement ? t.localName : "CSS rule";
778
- throw new g(
779
+ throw new y(
779
780
  `component ${this.#t.elementName}` + (t ? `, element "${i}"` : "") + (e ? `, attribute "${e}"` : "") + ` ${s}`
780
781
  );
781
782
  }
@@ -814,7 +815,7 @@ class d extends at {
814
815
  #_(t, e, s, i) {
815
816
  if (I(s) && !this.#a(t)) {
816
817
  const o = e === Boolean ? this.hasAttribute(i) : this.#C(t, i);
817
- s !== o && ot(this, i || t, s);
818
+ s !== o && it(this, i || t, s);
818
819
  }
819
820
  }
820
821
  // Updates all computed properties that reference this property.
@@ -838,14 +839,14 @@ class d extends at {
838
839
  if (t instanceof HTMLElement && S(t))
839
840
  t.value = o;
840
841
  else if (s && i === "string" && o.trim().startsWith("<")) {
841
- const n = rt(o);
842
+ const n = ct(o);
842
843
  t.innerHTML = n, this.#$(t), this.#M(t);
843
844
  } else s && (t.textContent = o);
844
845
  }
845
846
  // Update corresponding parent web component property if bound to one.
846
847
  // VS Code thinks this is never called, but it is called by #defineProp.
847
848
  #I(t, e) {
848
- const s = this.#g.get(t);
849
+ const s = this.#y.get(t);
849
850
  if (!s) return;
850
851
  const i = this.getRootNode();
851
852
  if (!(i instanceof ShadowRoot)) return;
@@ -871,7 +872,7 @@ class d extends at {
871
872
  }
872
873
  const { properties: s, propToExprsMap: i } = t;
873
874
  for (const [o, n] of Object.entries(s)) {
874
- const { usedBy: c } = n;
875
+ const c = Z(n.usedBy);
875
876
  if (!c) continue;
876
877
  t.methodToExprsMap || e.call(this);
877
878
  const { methodToExprsMap: a } = t;
@@ -879,7 +880,7 @@ class d extends at {
879
880
  f || (f = [], i.set(o, f));
880
881
  for (const h of c) {
881
882
  if (typeof this[h] != "function")
882
- throw new g(
883
+ throw new y(
883
884
  `property ${o} usedBy contains non-method ${h}`
884
885
  );
885
886
  const l = a.get(h) || [];
@@ -910,7 +911,7 @@ class d extends at {
910
911
  #D() {
911
912
  const t = new Set(Object.keys(this.#t.properties));
912
913
  for (const e of this.getAttributeNames())
913
- if (!ct.has(e) && !e.startsWith("on")) {
914
+ if (!at.has(e) && !e.startsWith("on")) {
914
915
  if (e === "form-assoc") {
915
916
  this.#A();
916
917
  continue;
@@ -924,7 +925,7 @@ class d extends at {
924
925
  }
925
926
  }
926
927
  }
927
- #y(t, e, s) {
928
+ #g(t, e, s) {
928
929
  const i = s.match(j);
929
930
  if (i)
930
931
  return i.forEach((o) => {
@@ -976,9 +977,9 @@ class d extends at {
976
977
  let c = n.slice(2);
977
978
  c = c[0].toLowerCase() + c.slice(1).toLowerCase();
978
979
  const a = o.value;
979
- this.#y(s, n, a);
980
+ this.#g(s, n, a);
980
981
  let f;
981
- typeof this[a] == "function" ? f = (h) => this[a](h) : (this.#y(s, n, a), f = () => this.#o(a)), s.addEventListener(c, f), i.push(n);
982
+ typeof this[a] == "function" ? f = (h) => this[a](h) : (this.#g(s, n, a), f = () => this.#o(a)), s.addEventListener(c, f), i.push(n);
982
983
  }
983
984
  }
984
985
  for (const o of i)
@@ -986,32 +987,32 @@ class d extends at {
986
987
  }
987
988
  }
988
989
  }
989
- function Mt(r, ...t) {
990
- let e = et(r, t);
990
+ function At(r, ...t) {
991
+ let e = st(r, t);
991
992
  for (; ; ) {
992
- const s = ft.exec(e);
993
+ const s = ht.exec(e);
993
994
  if (!s) break;
994
995
  const i = s[2];
995
- if (tt.test(i)) {
996
+ if (et.test(i)) {
996
997
  const o = s[1];
997
998
  if (!o.startsWith("--")) {
998
999
  const n = `--${o}: ${i};
999
1000
  ${o}: var(--${o})`;
1000
- e = st(e, s.index, s[0].length, n);
1001
+ e = ot(e, s.index, s[0].length, n);
1001
1002
  }
1002
1003
  }
1003
1004
  }
1004
1005
  return e;
1005
1006
  }
1006
- function At(r, ...t) {
1007
- let e = et(r, t);
1007
+ function St(r, ...t) {
1008
+ let e = st(r, t);
1008
1009
  for (; ; ) {
1009
- const s = pt.exec(e);
1010
+ const s = ut.exec(e);
1010
1011
  if (!s || s[1] === "style") break;
1011
- const i = bt(s[2]);
1012
- if (tt.test(i)) {
1012
+ const i = yt(s[2]);
1013
+ if (et.test(i)) {
1013
1014
  const o = `<!-- ${i.trim()} -->`, n = s.index + s[0].indexOf(">") + 1;
1014
- e = st(e, n, i.length, o);
1015
+ e = ot(e, n, i.length, o);
1015
1016
  }
1016
1017
  }
1017
1018
  return e;
@@ -1019,7 +1020,7 @@ function At(r, ...t) {
1019
1020
  export {
1020
1021
  d as Wrec,
1021
1022
  _ as WrecState,
1022
- Tt as createElement,
1023
- Mt as css,
1024
- At as html
1023
+ Mt as createElement,
1024
+ At as css,
1025
+ St as html
1025
1026
  };
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "wrec",
3
3
  "description": "a small library that greatly simplifies building web components",
4
4
  "author": "R. Mark Volkmann",
5
- "version": "0.24.0",
5
+ "version": "0.24.2",
6
6
  "license": "MIT",
7
7
  "repository": {
8
8
  "type": "git",
@@ -42,9 +42,7 @@ for (const target of targets) {
42
42
  }
43
43
 
44
44
  if (!/\.(js|ts)$/.test(target) || /\.d\.ts$/.test(target)) {
45
- console.error(
46
- `Unsupported file type: ${path.relative(cwd, target)}`
47
- );
45
+ console.error(`Unsupported file type: ${path.relative(cwd, target)}`);
48
46
  process.exit(1);
49
47
  }
50
48
  }
@@ -97,8 +95,9 @@ function hasStaticModifier(node) {
97
95
  );
98
96
  }
99
97
 
100
- function getWrecNames(sourceFile) {
98
+ function getWrecImportInfo(sourceFile) {
101
99
  const names = new Set(['Wrec']);
100
+ let quote = "'";
102
101
 
103
102
  for (const statement of sourceFile.statements) {
104
103
  if (
@@ -122,11 +121,18 @@ function getWrecNames(sourceFile) {
122
121
 
123
122
  for (const element of namedBindings.elements) {
124
123
  const importedName = element.propertyName?.text ?? element.name.text;
125
- if (importedName === 'Wrec') names.add(element.name.text);
124
+ if (importedName === 'Wrec') {
125
+ names.add(element.name.text);
126
+
127
+ const moduleText = statement.moduleSpecifier.getText(sourceFile);
128
+ if (moduleText.startsWith('"') || moduleText.startsWith("'")) {
129
+ quote = moduleText[0];
130
+ }
131
+ }
126
132
  }
127
133
  }
128
134
 
129
- return names;
135
+ return {names, quote};
130
136
  }
131
137
 
132
138
  function extendsWrec(node, wrecNames) {
@@ -389,8 +395,11 @@ function getMethodUsages(classNode, propertyNames) {
389
395
  return propToMethods;
390
396
  }
391
397
 
392
- function createUsedByProperty(methodNames) {
393
- return `usedBy: [${methodNames.map(name => `'${name}'`).join(', ')}]`;
398
+ function createUsedByProperty(methodNames, quote) {
399
+ if (methodNames.length === 1) {
400
+ return `usedBy: ${quote}${methodNames[0]}${quote}`;
401
+ }
402
+ return `usedBy: [${methodNames.map(name => `${quote}${name}${quote}`).join(', ')}]`;
394
403
  }
395
404
 
396
405
  function getIndent(text, pos) {
@@ -399,7 +408,7 @@ function getIndent(text, pos) {
399
408
  return match ? match[0] : '';
400
409
  }
401
410
 
402
- function buildConfigText(sourceFile, member, methodNames) {
411
+ function buildConfigText(sourceFile, member, methodNames, quote) {
403
412
  const {text} = sourceFile;
404
413
  const configObject = member.initializer;
405
414
  const existingMembers = configObject.properties.filter(
@@ -413,7 +422,7 @@ function buildConfigText(sourceFile, member, methodNames) {
413
422
  text.slice(property.getStart(sourceFile), property.end).trim()
414
423
  );
415
424
  if (methodNames.length > 0)
416
- existingTexts.push(createUsedByProperty(methodNames));
425
+ existingTexts.push(createUsedByProperty(methodNames, quote));
417
426
 
418
427
  const original = text.slice(
419
428
  configObject.getStart(sourceFile),
@@ -432,10 +441,12 @@ function buildConfigText(sourceFile, member, methodNames) {
432
441
 
433
442
  function transformSourceFile(sourceFile) {
434
443
  const edits = [];
435
- const wrecNames = getWrecNames(sourceFile);
444
+ const {names: wrecNames, quote} = getWrecImportInfo(sourceFile);
445
+ let foundWrecSubclass = false;
436
446
 
437
447
  for (const node of sourceFile.statements) {
438
448
  if (!ts.isClassDeclaration(node) || !extendsWrec(node, wrecNames)) continue;
449
+ foundWrecSubclass = true;
439
450
 
440
451
  let propertiesObject = null;
441
452
  for (const member of node.members) {
@@ -484,7 +495,7 @@ function transformSourceFile(sourceFile) {
484
495
  const needsUsedBy = methodNames.length > 0;
485
496
  if (!hadUsedBy && !needsUsedBy) continue;
486
497
 
487
- const nextText = buildConfigText(sourceFile, member, methodNames);
498
+ const nextText = buildConfigText(sourceFile, member, methodNames, quote);
488
499
  const currentText = sourceFile.text.slice(
489
500
  configObject.getStart(sourceFile),
490
501
  configObject.end
@@ -501,8 +512,22 @@ function transformSourceFile(sourceFile) {
501
512
  }
502
513
  }
503
514
 
515
+ if (!foundWrecSubclass) {
516
+ return {
517
+ changed: false,
518
+ edits: [],
519
+ foundWrecSubclass: false,
520
+ text: sourceFile.text
521
+ };
522
+ }
523
+
504
524
  if (edits.length === 0) {
505
- return {changed: false, edits: [], text: sourceFile.text};
525
+ return {
526
+ changed: false,
527
+ edits: [],
528
+ foundWrecSubclass: true,
529
+ text: sourceFile.text
530
+ };
506
531
  }
507
532
 
508
533
  let nextSource = sourceFile.text;
@@ -512,7 +537,7 @@ function transformSourceFile(sourceFile) {
512
537
  nextSource.slice(0, edit.start) + edit.text + nextSource.slice(edit.end);
513
538
  }
514
539
 
515
- return {changed: true, edits, text: nextSource};
540
+ return {changed: true, edits, foundWrecSubclass: true, text: nextSource};
516
541
  }
517
542
 
518
543
  let changedCount = 0;
@@ -528,13 +553,22 @@ for (const file of files) {
528
553
  scriptKind
529
554
  );
530
555
 
531
- const {changed, edits, text: nextText} = transformSourceFile(sourceFile);
556
+ const {
557
+ changed,
558
+ edits,
559
+ foundWrecSubclass,
560
+ text: nextText
561
+ } = transformSourceFile(sourceFile);
562
+ if (!foundWrecSubclass) {
563
+ console.error('No class extending Wrec was found.');
564
+ process.exit(1);
565
+ }
532
566
  if (!changed) continue;
533
567
 
534
568
  changedCount++;
535
569
  if (dry) {
536
570
  for (const edit of edits.toReversed()) {
537
- const match = edit.text.match(/usedBy:\s*\[[^\]]*\]/);
571
+ const match = edit.text.match(/usedBy:\s*(?:['"][^'"]*['"]|\[[^\]]*\])/);
538
572
  const suggestion = match ? match[0] : 'remove usedBy';
539
573
  console.log(`${edit.propName} - ${suggestion}`);
540
574
  }