@dooboostore/simple-web-component 1.0.55 → 1.0.56

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/README.md CHANGED
@@ -1992,6 +1992,40 @@ constructor(private service: Service) { super(); } // Web Components can't have
1992
1992
 
1993
1993
  ---
1994
1994
 
1995
+ ## ⚡ Benchmarks
1996
+
1997
+ Measured in real Chrome against a hand-written `innerHTML` renderer and Lit, rendering the same 1,000-row table (state in fields, a decorated method returns the HTML, `@replaceChildren*` applies it):
1998
+
1999
+ - **Bulk rendering keeps up with Lit.** Creating 10,000 rows takes 244 ms, versus 232 ms for Lit and 222 ms for a hand-written `innerHTML` loop.
2000
+ - **Low memory.** 1,000 rows keep about 94 KB of JS heap, 6x less than Lit (558 KB); at 10,000 rows it is 1.6 MB versus 4.9 MB (3x less). Only the data is retained, no per-row template bookkeeping.
2001
+ - **Thin layer.** Rendering through the decorators costs within about 5% to 25% of the equivalent hand-written `innerHTML` code.
2002
+
2003
+ ```text
2004
+ create 10,000 rows (lower is better)
2005
+ vanilla (innerHTML) ██████████████████████████ 222 ▲
2006
+ lit ████████████████████████████ 232
2007
+ simple-web-component █████████████████████████████ 244
2008
+ vanilla (DOM calls) ████████████████████████████████ 269
2009
+
2010
+ JS heap, 1,000 rows (KB) (lower is better)
2011
+ vanilla (innerHTML) ████ 73.4 ▲
2012
+ simple-web-component █████ 93.5
2013
+ vanilla (DOM calls) ███████ 119
2014
+ lit ████████████████████████████████ 558
2015
+ ```
2016
+
2017
+ Full results, including the operations where other approaches are faster, methodology and caveats: [bench/RESULTS.md](./bench/RESULTS.md). Reproduce with `pnpm bench` inside `bench/`.
2018
+
2019
+ ---
2020
+
2021
+ ## 🧰 Editor Support (LSP)
2022
+
2023
+ The package ships a language server for SWC templates — `npx swc-lsp --stdio`:
2024
+ tag / attribute / `@state@` / `$host.` completion, hover, go to definition, parameter hints, and type errors inside `swc-on-*`, `{{= }}` and `@x@`
2025
+ (`swc-on-click="$host.tt(4)"` → *number is not assignable to string*).
2026
+
2027
+ Setup for IntelliJ, VS Code and Neovim: [lsp/README.md](https://github.com/dooboostore-develop/packages/tree/main/@dooboostore/simple-web-component/lsp).
2028
+
1995
2029
  ## 🧪 Testing
1996
2030
 
1997
2031
  `pnpm test` type-checks the tests and runs them in a real browser (Chromium via Playwright, falling back to the installed Chrome) — no jsdom. Each test gets its own same-origin iframe window, so custom elements, `history` and `location` never leak between tests.
@@ -30,9 +30,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
30
30
  ));
31
31
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
32
32
 
33
- // ../../../node_modules/.pnpm/reflect-metadata@0.2.2/node_modules/reflect-metadata/Reflect.js
33
+ // ../../node_modules/.pnpm/reflect-metadata@0.2.2/node_modules/reflect-metadata/Reflect.js
34
34
  var require_Reflect = __commonJS({
35
- "../../../node_modules/.pnpm/reflect-metadata@0.2.2/node_modules/reflect-metadata/Reflect.js"() {
35
+ "../../node_modules/.pnpm/reflect-metadata@0.2.2/node_modules/reflect-metadata/Reflect.js"() {
36
36
  var Reflect2;
37
37
  (function(Reflect3) {
38
38
  (function(factory) {
@@ -21124,26 +21124,45 @@ var SimstanceManager = class _SimstanceManager {
21124
21124
  return registed.instance;
21125
21125
  }
21126
21126
  if (this.storage.has(targetKey) && void 0 === registed?.instance) {
21127
- newInstanceCarrier.depth++;
21128
- const newSim = this.newSim({
21129
- target: registed?.type ?? targetKey,
21130
- newInstanceCarrier,
21131
- simCreateAfter: (data) => {
21132
- if (getSim(registed?.type ?? target ?? targetKey)?.scope === Lifecycle.Singleton) {
21133
- this.setStoreSet(targetKey, data, target);
21127
+ const resolving = newInstanceCarrier.resolving ?? (newInstanceCarrier.resolving = []);
21128
+ if (resolving.includes(targetKey)) {
21129
+ const nameOf = (t) => typeof t === "symbol" ? t.toString() : t?.name ?? String(t);
21130
+ throw new Error(
21131
+ `Circular dependency detected: ${[...resolving.map(nameOf), nameOf(targetKey)].join(" -> ")}`
21132
+ );
21133
+ }
21134
+ resolving.push(targetKey);
21135
+ let settled = false;
21136
+ try {
21137
+ newInstanceCarrier.depth++;
21138
+ const newSim = this.newSim({
21139
+ target: registed?.type ?? targetKey,
21140
+ newInstanceCarrier,
21141
+ simCreateAfter: (data) => {
21142
+ if (getSim(registed?.type ?? target ?? targetKey)?.scope === Lifecycle.Singleton) {
21143
+ this.setStoreSet(targetKey, data, target);
21144
+ }
21134
21145
  }
21135
- }
21136
- });
21137
- newInstanceCarrier.depth--;
21138
- if (newInstanceCarrier.depth === 0) {
21139
- newInstanceCarrier.newInstances.forEach((it) => {
21140
- this.callBindPostConstruct(it);
21141
21146
  });
21147
+ newInstanceCarrier.depth--;
21148
+ resolving.pop();
21149
+ settled = true;
21150
+ if (newInstanceCarrier.depth === 0) {
21151
+ newInstanceCarrier.newInstances.forEach((it) => {
21152
+ this.callBindPostConstruct(it);
21153
+ });
21154
+ }
21155
+ if (isOnSimCreate(newSim)) {
21156
+ newSim.onSimCreate();
21157
+ }
21158
+ return newSim;
21159
+ } finally {
21160
+ if (!settled) {
21161
+ newInstanceCarrier.depth--;
21162
+ const idx = resolving.lastIndexOf(targetKey);
21163
+ if (idx !== -1) resolving.splice(idx, 1);
21164
+ }
21142
21165
  }
21143
- if (isOnSimCreate(newSim)) {
21144
- newSim.onSimCreate();
21145
- }
21146
- return newSim;
21147
21166
  }
21148
21167
  const simNoSuch = new SimNoSuch("SimNoSuch: no simple instance(resolve) name:" + targetKey?.prototype?.constructor?.name + "," + targetKey);
21149
21168
  console.error(simNoSuch);