thunderous 1.1.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,437 +1,3 @@
1
- // vendor/@webcomponents/scoped-custom-element-registry/src/scoped-custom-element-registry.js
2
- if (typeof window !== "undefined") {
3
- if (!ShadowRoot.prototype.createElement) {
4
- const NativeHTMLElement = window.HTMLElement;
5
- const nativeDefine = window.customElements.define;
6
- const nativeGet = window.customElements.get;
7
- const nativeRegistry = window.customElements;
8
- const definitionForElement = /* @__PURE__ */ new WeakMap();
9
- const pendingRegistryForElement = /* @__PURE__ */ new WeakMap();
10
- const globalDefinitionForConstructor = /* @__PURE__ */ new WeakMap();
11
- const scopeForElement = /* @__PURE__ */ new WeakMap();
12
- window.CustomElementRegistry = class {
13
- constructor() {
14
- this._definitionsByTag = /* @__PURE__ */ new Map();
15
- this._definitionsByClass = /* @__PURE__ */ new Map();
16
- this._whenDefinedPromises = /* @__PURE__ */ new Map();
17
- this._awaitingUpgrade = /* @__PURE__ */ new Map();
18
- }
19
- define(tagName, elementClass) {
20
- tagName = tagName.toLowerCase();
21
- if (this._getDefinition(tagName) !== void 0) {
22
- throw new DOMException(
23
- `Failed to execute 'define' on 'CustomElementRegistry': the name "${tagName}" has already been used with this registry`
24
- );
25
- }
26
- if (this._definitionsByClass.get(elementClass) !== void 0) {
27
- throw new DOMException(
28
- `Failed to execute 'define' on 'CustomElementRegistry': this constructor has already been used with this registry`
29
- );
30
- }
31
- const attributeChangedCallback = elementClass.prototype.attributeChangedCallback;
32
- const observedAttributes = new Set(elementClass.observedAttributes || []);
33
- patchAttributes(
34
- elementClass,
35
- observedAttributes,
36
- attributeChangedCallback
37
- );
38
- const definition = {
39
- elementClass,
40
- connectedCallback: elementClass.prototype.connectedCallback,
41
- disconnectedCallback: elementClass.prototype.disconnectedCallback,
42
- adoptedCallback: elementClass.prototype.adoptedCallback,
43
- attributeChangedCallback,
44
- "formAssociated": elementClass["formAssociated"],
45
- "formAssociatedCallback": elementClass.prototype["formAssociatedCallback"],
46
- "formDisabledCallback": elementClass.prototype["formDisabledCallback"],
47
- "formResetCallback": elementClass.prototype["formResetCallback"],
48
- "formStateRestoreCallback": elementClass.prototype["formStateRestoreCallback"],
49
- observedAttributes
50
- };
51
- this._definitionsByTag.set(tagName, definition);
52
- this._definitionsByClass.set(elementClass, definition);
53
- let standInClass = nativeGet.call(nativeRegistry, tagName);
54
- if (!standInClass) {
55
- standInClass = createStandInElement(tagName);
56
- nativeDefine.call(nativeRegistry, tagName, standInClass);
57
- }
58
- if (this === window.customElements) {
59
- globalDefinitionForConstructor.set(elementClass, definition);
60
- definition.standInClass = standInClass;
61
- }
62
- const awaiting = this._awaitingUpgrade.get(tagName);
63
- if (awaiting) {
64
- this._awaitingUpgrade.delete(tagName);
65
- for (const element of awaiting) {
66
- pendingRegistryForElement.delete(element);
67
- customize(element, definition, true);
68
- }
69
- }
70
- const info = this._whenDefinedPromises.get(tagName);
71
- if (info !== void 0) {
72
- info.resolve(elementClass);
73
- this._whenDefinedPromises.delete(tagName);
74
- }
75
- return elementClass;
76
- }
77
- upgrade() {
78
- creationContext.push(this);
79
- nativeRegistry.upgrade.apply(nativeRegistry, arguments);
80
- creationContext.pop();
81
- }
82
- get(tagName) {
83
- const definition = this._definitionsByTag.get(tagName);
84
- return definition?.elementClass;
85
- }
86
- _getDefinition(tagName) {
87
- return this._definitionsByTag.get(tagName);
88
- }
89
- whenDefined(tagName) {
90
- const definition = this._getDefinition(tagName);
91
- if (definition !== void 0) {
92
- return Promise.resolve(definition.elementClass);
93
- }
94
- let info = this._whenDefinedPromises.get(tagName);
95
- if (info === void 0) {
96
- info = {};
97
- info.promise = new Promise((r) => info.resolve = r);
98
- this._whenDefinedPromises.set(tagName, info);
99
- }
100
- return info.promise;
101
- }
102
- _upgradeWhenDefined(element, tagName, shouldUpgrade) {
103
- let awaiting = this._awaitingUpgrade.get(tagName);
104
- if (!awaiting) {
105
- this._awaitingUpgrade.set(tagName, awaiting = /* @__PURE__ */ new Set());
106
- }
107
- if (shouldUpgrade) {
108
- awaiting.add(element);
109
- } else {
110
- awaiting.delete(element);
111
- }
112
- }
113
- };
114
- let upgradingInstance;
115
- window.HTMLElement = function HTMLElement2() {
116
- let instance = upgradingInstance;
117
- if (instance) {
118
- upgradingInstance = void 0;
119
- return instance;
120
- }
121
- const definition = globalDefinitionForConstructor.get(this.constructor);
122
- if (!definition) {
123
- throw new TypeError(
124
- "Illegal constructor (custom element class must be registered with global customElements registry to be newable)"
125
- );
126
- }
127
- instance = Reflect.construct(
128
- NativeHTMLElement,
129
- [],
130
- definition.standInClass
131
- );
132
- Object.setPrototypeOf(instance, this.constructor.prototype);
133
- definitionForElement.set(instance, definition);
134
- return instance;
135
- };
136
- window.HTMLElement.prototype = NativeHTMLElement.prototype;
137
- const isValidScope = (node) => node === document || node instanceof ShadowRoot;
138
- const registryForNode = (node) => {
139
- let scope = node.getRootNode();
140
- if (!isValidScope(scope)) {
141
- const context = creationContext[creationContext.length - 1];
142
- if (context instanceof CustomElementRegistry) {
143
- return context;
144
- }
145
- scope = context.getRootNode();
146
- if (!isValidScope(scope)) {
147
- scope = scopeForElement.get(scope)?.getRootNode() || document;
148
- }
149
- }
150
- return scope.customElements;
151
- };
152
- const createStandInElement = (tagName) => {
153
- return class ScopedCustomElementBase {
154
- static get ["formAssociated"]() {
155
- return true;
156
- }
157
- constructor() {
158
- const instance = Reflect.construct(
159
- NativeHTMLElement,
160
- [],
161
- this.constructor
162
- );
163
- Object.setPrototypeOf(instance, HTMLElement.prototype);
164
- const registry = registryForNode(instance) || window.customElements;
165
- const definition = registry._getDefinition(tagName);
166
- if (definition) {
167
- customize(instance, definition);
168
- } else {
169
- pendingRegistryForElement.set(instance, registry);
170
- }
171
- return instance;
172
- }
173
- connectedCallback() {
174
- const definition = definitionForElement.get(this);
175
- if (definition) {
176
- definition.connectedCallback && definition.connectedCallback.apply(this, arguments);
177
- } else {
178
- pendingRegistryForElement.get(this)._upgradeWhenDefined(this, tagName, true);
179
- }
180
- }
181
- disconnectedCallback() {
182
- const definition = definitionForElement.get(this);
183
- if (definition) {
184
- definition.disconnectedCallback && definition.disconnectedCallback.apply(this, arguments);
185
- } else {
186
- pendingRegistryForElement.get(this)._upgradeWhenDefined(this, tagName, false);
187
- }
188
- }
189
- adoptedCallback() {
190
- const definition = definitionForElement.get(this);
191
- definition?.adoptedCallback?.apply(this, arguments);
192
- }
193
- // Form-associated custom elements lifecycle methods
194
- ["formAssociatedCallback"]() {
195
- const definition = definitionForElement.get(this);
196
- if (definition && definition["formAssociated"]) {
197
- definition?.["formAssociatedCallback"]?.apply(this, arguments);
198
- }
199
- }
200
- ["formDisabledCallback"]() {
201
- const definition = definitionForElement.get(this);
202
- if (definition?.["formAssociated"]) {
203
- definition?.["formDisabledCallback"]?.apply(this, arguments);
204
- }
205
- }
206
- ["formResetCallback"]() {
207
- const definition = definitionForElement.get(this);
208
- if (definition?.["formAssociated"]) {
209
- definition?.["formResetCallback"]?.apply(this, arguments);
210
- }
211
- }
212
- ["formStateRestoreCallback"]() {
213
- const definition = definitionForElement.get(this);
214
- if (definition?.["formAssociated"]) {
215
- definition?.["formStateRestoreCallback"]?.apply(this, arguments);
216
- }
217
- }
218
- // no attributeChangedCallback or observedAttributes since these
219
- // are simulated via setAttribute/removeAttribute patches
220
- };
221
- };
222
- const patchAttributes = (elementClass, observedAttributes, attributeChangedCallback) => {
223
- if (observedAttributes.size === 0 || attributeChangedCallback === void 0) {
224
- return;
225
- }
226
- const setAttribute = elementClass.prototype.setAttribute;
227
- if (setAttribute) {
228
- elementClass.prototype.setAttribute = function(n, value) {
229
- const name = n.toLowerCase();
230
- if (observedAttributes.has(name)) {
231
- const old = this.getAttribute(name);
232
- setAttribute.call(this, name, value);
233
- attributeChangedCallback.call(this, name, old, value);
234
- } else {
235
- setAttribute.call(this, name, value);
236
- }
237
- };
238
- }
239
- const removeAttribute = elementClass.prototype.removeAttribute;
240
- if (removeAttribute) {
241
- elementClass.prototype.removeAttribute = function(n) {
242
- const name = n.toLowerCase();
243
- if (observedAttributes.has(name)) {
244
- const old = this.getAttribute(name);
245
- removeAttribute.call(this, name);
246
- attributeChangedCallback.call(this, name, old, null);
247
- } else {
248
- removeAttribute.call(this, name);
249
- }
250
- };
251
- }
252
- const toggleAttribute = elementClass.prototype.toggleAttribute;
253
- if (toggleAttribute) {
254
- elementClass.prototype.toggleAttribute = function(n, force) {
255
- const name = n.toLowerCase();
256
- if (observedAttributes.has(name)) {
257
- const old = this.getAttribute(name);
258
- toggleAttribute.call(this, name, force);
259
- const newValue = this.getAttribute(name);
260
- attributeChangedCallback.call(this, name, old, newValue);
261
- } else {
262
- toggleAttribute.call(this, name, force);
263
- }
264
- };
265
- }
266
- };
267
- const patchHTMLElement = (elementClass) => {
268
- const parentClass = Object.getPrototypeOf(elementClass);
269
- if (parentClass !== window.HTMLElement) {
270
- if (parentClass === NativeHTMLElement) {
271
- return Object.setPrototypeOf(elementClass, window.HTMLElement);
272
- }
273
- return patchHTMLElement(parentClass);
274
- }
275
- };
276
- const customize = (instance, definition, isUpgrade = false) => {
277
- Object.setPrototypeOf(instance, definition.elementClass.prototype);
278
- definitionForElement.set(instance, definition);
279
- upgradingInstance = instance;
280
- try {
281
- new definition.elementClass();
282
- } catch (_) {
283
- patchHTMLElement(definition.elementClass);
284
- new definition.elementClass();
285
- }
286
- if (definition.attributeChangedCallback) {
287
- definition.observedAttributes.forEach((attr) => {
288
- if (instance.hasAttribute(attr)) {
289
- definition.attributeChangedCallback.call(
290
- instance,
291
- attr,
292
- null,
293
- instance.getAttribute(attr)
294
- );
295
- }
296
- });
297
- }
298
- if (isUpgrade && definition.connectedCallback && instance.isConnected) {
299
- definition.connectedCallback.call(instance);
300
- }
301
- };
302
- const nativeAttachShadow = Element.prototype.attachShadow;
303
- Element.prototype.attachShadow = function(init) {
304
- const shadowRoot = nativeAttachShadow.apply(this, arguments);
305
- if (init.customElements) {
306
- shadowRoot.customElements = init.customElements;
307
- }
308
- return shadowRoot;
309
- };
310
- let creationContext = [document];
311
- const installScopedCreationMethod = (ctor, method, from = void 0) => {
312
- const native = (from ? Object.getPrototypeOf(from) : ctor.prototype)[method];
313
- ctor.prototype[method] = function() {
314
- creationContext.push(this);
315
- const ret = native.apply(from || this, arguments);
316
- if (ret !== void 0) {
317
- scopeForElement.set(ret, this);
318
- }
319
- creationContext.pop();
320
- return ret;
321
- };
322
- };
323
- installScopedCreationMethod(ShadowRoot, "createElement", document);
324
- installScopedCreationMethod(ShadowRoot, "importNode", document);
325
- installScopedCreationMethod(Element, "insertAdjacentHTML");
326
- const installScopedCreationSetter = (ctor, name) => {
327
- const descriptor = Object.getOwnPropertyDescriptor(ctor.prototype, name);
328
- Object.defineProperty(ctor.prototype, name, {
329
- ...descriptor,
330
- set(value) {
331
- creationContext.push(this);
332
- descriptor.set.call(this, value);
333
- creationContext.pop();
334
- }
335
- });
336
- };
337
- installScopedCreationSetter(Element, "innerHTML");
338
- installScopedCreationSetter(ShadowRoot, "innerHTML");
339
- Object.defineProperty(window, "customElements", {
340
- value: new CustomElementRegistry(),
341
- configurable: true,
342
- writable: true
343
- });
344
- if (!!window["ElementInternals"] && !!window["ElementInternals"].prototype["setFormValue"]) {
345
- const internalsToHostMap = /* @__PURE__ */ new WeakMap();
346
- const attachInternals = HTMLElement.prototype["attachInternals"];
347
- const methods = [
348
- "setFormValue",
349
- "setValidity",
350
- "checkValidity",
351
- "reportValidity"
352
- ];
353
- HTMLElement.prototype["attachInternals"] = function(...args) {
354
- const internals = attachInternals.call(this, ...args);
355
- internalsToHostMap.set(internals, this);
356
- return internals;
357
- };
358
- methods.forEach((method) => {
359
- const proto = window["ElementInternals"].prototype;
360
- const originalMethod = proto[method];
361
- proto[method] = function(...args) {
362
- const host = internalsToHostMap.get(this);
363
- const definition = definitionForElement.get(host);
364
- if (definition["formAssociated"] === true) {
365
- return originalMethod?.call(this, ...args);
366
- } else {
367
- throw new DOMException(
368
- `Failed to execute ${originalMethod} on 'ElementInternals': The target element is not a form-associated custom element.`
369
- );
370
- }
371
- };
372
- });
373
- class RadioNodeList extends Array {
374
- constructor(elements) {
375
- super(...elements);
376
- this._elements = elements;
377
- }
378
- get ["value"]() {
379
- return this._elements.find((element) => element["checked"] === true)?.value || "";
380
- }
381
- }
382
- class HTMLFormControlsCollection {
383
- constructor(elements) {
384
- const entries = /* @__PURE__ */ new Map();
385
- elements.forEach((element, index) => {
386
- const name = element.getAttribute("name");
387
- const nameReference = entries.get(name) || [];
388
- this[+index] = element;
389
- nameReference.push(element);
390
- entries.set(name, nameReference);
391
- });
392
- this["length"] = elements.length;
393
- entries.forEach((value, key) => {
394
- if (!value) return;
395
- if (value.length === 1) {
396
- this[key] = value[0];
397
- } else {
398
- this[key] = new RadioNodeList(value);
399
- }
400
- });
401
- }
402
- ["namedItem"](key) {
403
- return this[key];
404
- }
405
- }
406
- const formElementsDescriptor = Object.getOwnPropertyDescriptor(
407
- HTMLFormElement.prototype,
408
- "elements"
409
- );
410
- Object.defineProperty(HTMLFormElement.prototype, "elements", {
411
- get: function() {
412
- const nativeElements = formElementsDescriptor.get.call(this, []);
413
- const include = [];
414
- for (const element of nativeElements) {
415
- const definition = definitionForElement.get(element);
416
- if (!definition || definition["formAssociated"] === true) {
417
- include.push(element);
418
- }
419
- }
420
- return new HTMLFormControlsCollection(include);
421
- }
422
- });
423
- }
424
- }
425
- class TrackableCustomElementRegistry extends window.CustomElementRegistry {
426
- __tagNames = /* @__PURE__ */ new Set();
427
- define(tagName, constructor, options) {
428
- super.define(tagName, constructor, options);
429
- this.__tagNames.add(tagName);
430
- }
431
- }
432
- window.CustomElementRegistry = TrackableCustomElementRegistry;
433
- }
434
-
435
1
  // src/constants.ts
436
2
  var DEFAULT_RENDER_OPTIONS = {
437
3
  formAssociated: false,
@@ -474,6 +40,7 @@ var createSignal = (initVal, options) => {
474
40
  }
475
41
  return value;
476
42
  };
43
+ getter.getter = true;
477
44
  const setter = (newValue, setterOptions) => {
478
45
  const isObject = typeof newValue === "object" && newValue !== null;
479
46
  if (!isObject && value === newValue) return;
@@ -610,7 +177,12 @@ var getServerRenderArgs = (tagName, registry) => ({
610
177
  formStateRestoreCallback: NOOP,
611
178
  formAssociatedCallback: NOOP,
612
179
  clientOnlyCallback: NOOP,
613
- customCallback: () => `{{callback:unavailable-on-server}}`,
180
+ customCallback: () => "",
181
+ getter: (fn) => {
182
+ const _fn = () => fn();
183
+ _fn.getter = true;
184
+ return _fn;
185
+ },
614
186
  attrSignals: new Proxy({}, { get: (_, attr) => createSignal(`{{attr:${String(attr)}}}`) }),
615
187
  propSignals: new Proxy({}, { get: () => createSignal(null) }),
616
188
  refs: {},
@@ -730,13 +302,14 @@ var getNewNode = (value, parent) => {
730
302
  var html = (strings, ...values) => {
731
303
  let innerHTML = "";
732
304
  const signalMap = /* @__PURE__ */ new Map();
305
+ const callbackMap = /* @__PURE__ */ new Map();
733
306
  const processValue = (value) => {
734
307
  if (!isServer && value instanceof DocumentFragment) {
735
308
  const tempDiv = document.createElement("div");
736
309
  tempDiv.append(value.cloneNode(true));
737
310
  return tempDiv.innerHTML;
738
311
  }
739
- if (typeof value === "function") {
312
+ if (typeof value === "function" && "getter" in value && value.getter === true) {
740
313
  const getter = value;
741
314
  const uniqueKey = crypto.randomUUID();
742
315
  signalMap.set(uniqueKey, getter);
@@ -746,6 +319,11 @@ var html = (strings, ...values) => {
746
319
  }
747
320
  return isServer ? String(result) : `{{signal:${uniqueKey}}}`;
748
321
  }
322
+ if (typeof value === "function") {
323
+ const uniqueKey = crypto.randomUUID();
324
+ callbackMap.set(uniqueKey, value);
325
+ return isServer ? String(value()) : `{{callback:${uniqueKey}}}`;
326
+ }
749
327
  if (typeof value === "object" && value !== null) {
750
328
  logValueError(value);
751
329
  return "";
@@ -766,6 +344,7 @@ var html = (strings, ...values) => {
766
344
  }
767
345
  const fragment = parseFragment(innerHTML);
768
346
  const callbackBindingRegex = /(\{\{callback:.+\}\})/;
347
+ const legacyCallbackBindingRegex = /(this.getRootNode\(\).host.__customCallbackFns.get\('.+'\)\(event\))/;
769
348
  const signalBindingRegex = /(\{\{signal:.+\}\})/;
770
349
  const parseChildren = (element) => {
771
350
  for (const child of element.childNodes) {
@@ -828,14 +407,29 @@ var html = (strings, ...values) => {
828
407
  child.setAttribute(attr.name, newText);
829
408
  }
830
409
  });
831
- } else if (callbackBindingRegex.test(attr.value)) {
410
+ } else if (legacyCallbackBindingRegex.test(attr.value)) {
832
411
  const getRootNode = child.getRootNode.bind(child);
833
412
  child.getRootNode = () => {
834
413
  const rootNode = getRootNode();
835
414
  return rootNode instanceof ShadowRoot ? rootNode : fragment;
836
415
  };
837
- const uniqueKey = attr.value.replace(/\{\{callback:(.+)\}\}/, "$1");
838
- child.setAttribute(attr.name, `this.getRootNode().host.__customCallbackFns.get('${uniqueKey}')(event)`);
416
+ } else if (callbackBindingRegex.test(attr.value)) {
417
+ const textList = attr.value.split(callbackBindingRegex);
418
+ createEffect(() => {
419
+ child.__customCallbackFns = child.__customCallbackFns ?? /* @__PURE__ */ new Map();
420
+ let uniqueKey = "";
421
+ for (const text of textList) {
422
+ const _uniqueKey = text.replace(/\{\{callback:(.+)\}\}/, "$1");
423
+ if (_uniqueKey !== text) uniqueKey = _uniqueKey;
424
+ const callback = uniqueKey !== text ? callbackMap.get(uniqueKey) : void 0;
425
+ if (callback !== void 0) {
426
+ child.__customCallbackFns.set(uniqueKey, callback);
427
+ }
428
+ }
429
+ if (uniqueKey !== "") {
430
+ child.setAttribute(attr.name, `this.__customCallbackFns.get('${uniqueKey}')(event)`);
431
+ }
432
+ });
839
433
  }
840
434
  }
841
435
  parseChildren(child);
@@ -1000,10 +594,15 @@ var customElement = (render, options) => {
1000
594
  formResetCallback: (fn) => this.#formResetCallbackFns.add(fn),
1001
595
  formStateRestoreCallback: (fn) => this.#formStateRestoreCallbackFns.add(fn),
1002
596
  clientOnlyCallback: (fn) => this.#clientOnlyCallbackFns.add(fn),
597
+ getter: (fn) => {
598
+ const _fn = () => fn();
599
+ _fn.getter = true;
600
+ return _fn;
601
+ },
1003
602
  customCallback: (fn) => {
1004
603
  const key = crypto.randomUUID();
1005
604
  this.__customCallbackFns.set(key, fn);
1006
- return `{{callback:${key}}}`;
605
+ return `this.getRootNode().host.__customCallbackFns.get('${key}')(event)`;
1007
606
  },
1008
607
  attrSignals: new Proxy(
1009
608
  {},
@@ -1041,6 +640,7 @@ You must set an initial value before calling a property signal's getter.
1041
640
  );
1042
641
  return value;
1043
642
  };
643
+ getter.getter = true;
1044
644
  return [getter, setter];
1045
645
  },
1046
646
  set: () => {
@@ -1286,16 +886,3 @@ export {
1286
886
  insertTemplates,
1287
887
  onServerDefine
1288
888
  };
1289
- /**
1290
- * @license
1291
- * Copyright (c) 2020 The Polymer Project Authors. All rights reserved.
1292
- * This code may only be used under the BSD style license found at
1293
- * http://polymer.github.io/LICENSE.txt
1294
- * The complete set of authors may be found at
1295
- * http://polymer.github.io/AUTHORS.txt
1296
- * The complete set of contributors may be found at
1297
- * http://polymer.github.io/CONTRIBUTORS.txt
1298
- * Code distributed by Google as part of the polymer project is also
1299
- * subject to an additional IP rights grant found at
1300
- * http://polymer.github.io/PATENTS.txt
1301
- */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thunderous",
3
- "version": "1.1.1",
3
+ "version": "2.0.0",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -53,5 +53,13 @@
53
53
  "tsup": "^8.3.0",
54
54
  "tsx": "^4.19.2",
55
55
  "typescript": "^5.7.2"
56
+ },
57
+ "peerDependencies": {
58
+ "@webcomponents/scoped-custom-element-registry": "^0.0.10"
59
+ },
60
+ "peerDependenciesMeta": {
61
+ "@webcomponents/scoped-custom-element-registry": {
62
+ "optional": true
63
+ }
56
64
  }
57
65
  }