@symbiotejs/symbiote 3.4.5 → 3.4.7

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/AI_REFERENCE.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Symbiote.js — AI Context Reference (v3.x)
2
2
 
3
3
  > **Purpose**: Authoritative reference for AI code assistants. All information is derived from source code analysis of [symbiote.js](https://github.com/symbiotejs/symbiote.js).
4
- > Current version: **3.4.3**. Zero dependencies. ~6.3 KB brotli / ~7 KB gzip.
4
+ > Current version: **3.4.7**. Zero dependencies. ~6.4 KB brotli / ~7.1 KB gzip.
5
5
 
6
6
  ---
7
7
 
package/CHANGELOG.md CHANGED
@@ -1,10 +1,12 @@
1
1
  # Changelog
2
2
 
3
- ## 3.4.5
3
+ ## 3.4.7
4
4
 
5
5
  ### Fixed
6
6
 
7
7
  - **PubSub: computed properties with cross-context deps no longer depend on import order.** When a computed property declared `deps: ['CTX/prop']` and the target context wasn't registered yet, the subscription was silently skipped. Now deferred deps are stored in `PubSub.pendingDeps` and automatically resolved when `registerCtx()` is called.
8
+ - **Symbiote: named context access no longer crashes when context is not yet registered.** The `$` proxy, `sub()`, `notify()`, `has()`, and `add()` now handle missing named contexts gracefully (return `undefined`/no-op instead of throwing).
9
+ - **Symbiote: template bindings for named contexts are deferred when context is not yet registered.** Previously, `sub()` silently dropped the subscription; now it queues it via `PubSub.pendingDeps` and resolves automatically when `registerCtx()` is called.
8
10
 
9
11
  ## 3.4.4
10
12
 
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  [![Tests](https://github.com/symbiotejs/symbiote.js/actions/workflows/tests.yml/badge.svg)](https://github.com/symbiotejs/symbiote.js/actions/workflows/tests.yml)
2
2
  [![npm version](https://img.shields.io/npm/v/@symbiotejs/symbiote)](https://www.npmjs.com/package/@symbiotejs/symbiote)
3
3
  [![npm downloads](https://img.shields.io/npm/dm/@symbiotejs/symbiote)](https://www.npmjs.com/package/@symbiotejs/symbiote)
4
- ![bundle size](https://img.shields.io/badge/brotli-6.3_kb-blue)
4
+ ![bundle size](https://img.shields.io/badge/brotli-6.4_kb-blue)
5
5
  ![types](https://img.shields.io/badge/types-JSDoc+d.ts-blue)
6
6
  ![license](https://img.shields.io/badge/license-MIT-green)
7
7
 
@@ -9,7 +9,7 @@
9
9
 
10
10
  <img src="https://rnd-pro.com/svg/symbiote/index.svg" width="200" alt="Symbiote.js">
11
11
 
12
- A lightweight, standards-first UI library built on Web Components. No virtual DOM, no compiler, no build step required — works directly in the browser. A bundler is recommended for production performance, but entirely optional. **~6.3kb** brotli / **~7kb** gzip.
12
+ A lightweight, standards-first UI library built on Web Components. No virtual DOM, no compiler, no build step required — works directly in the browser. A bundler is recommended for production performance, but entirely optional. **~6kb** brotli / **~7kb** gzip.
13
13
 
14
14
  Symbiote.js gives you the convenience of a modern framework while staying close to the native platform — HTML, CSS, and DOM APIs. Components are real custom elements that work everywhere: in any framework, in plain HTML, or in a micro-frontend architecture. And with **isomorphic mode**, the same component code works on the server and the client — server-rendered pages hydrate automatically, no diffing, no mismatch errors.
15
15
 
@@ -344,12 +344,12 @@ CSS values are parsed automatically — quoted strings become strings, numbers b
344
344
 
345
345
  | Library | Minified | Gzip | Brotli |
346
346
  |---------|----------|------|--------|
347
- | **Symbiote.js** (core) | 19.8 kb | 6.9 kb | **6.3 kb** |
348
- | **Symbiote.js** (full, with AppRouter) | 24.0 kb | 8.3 kb | **7.5 kb** |
347
+ | **Symbiote.js** (core) | 20.2 kb | 7.1 kb | **6.4 kb** |
348
+ | **Symbiote.js** (full, with AppRouter) | 24.4 kb | 8.5 kb | **7.6 kb** |
349
349
  | **Lit** 3.3 | 15.5 kb | 6.0 kb | **~5.1 kb** |
350
350
  | **React 19 + ReactDOM** | ~186 kb | ~59 kb | **~50 kb** |
351
351
 
352
- Symbiote and Lit have similar base sizes, but Symbiote's **6.3 kb** core includes more built-in features: global state management, lists (itemize API), exit animations, computed properties etc. Lit needs additional packages for comparable features. React is **~8× larger** before adding a router, state manager, or SSR framework.
352
+ Symbiote and Lit have similar base sizes, but Symbiote's **6.4 kb** core includes more built-in features: global state management, lists (itemize API), exit animations, computed properties etc. Lit needs additional packages for comparable features. React is **~8× larger** before adding a router, state manager, or SSR framework.
353
353
 
354
354
  ## Browser support
355
355
 
package/core/Symbiote.js CHANGED
@@ -247,7 +247,10 @@ export class Symbiote extends HTMLElement {
247
247
  ctx = found?.localCtx || fnCtx.localCtx;
248
248
  } else if (prop.includes('/')) {
249
249
  let slashIdx = prop.indexOf('/');
250
- ctx = PubSub.getCtx(prop.slice(0, slashIdx));
250
+ ctx = PubSub.getCtx(prop.slice(0, slashIdx), false);
251
+ if (!ctx) {
252
+ return null;
253
+ }
251
254
  name = prop.slice(slashIdx + 1);
252
255
  } else if (first === 45 && prop.charCodeAt(1) === 45) {
253
256
  ctx = fnCtx.localCtx;
@@ -276,6 +279,26 @@ export class Symbiote extends HTMLElement {
276
279
  handler(val);
277
280
  };
278
281
  let parsed = Symbiote.#parseProp(/** @type {string} */ (prop), this);
282
+ if (!parsed) {
283
+ // Named context not found — defer subscription
284
+ let slashIdx = /** @type {string} */ (prop).indexOf('/');
285
+ if (slashIdx !== -1) {
286
+ let ctxName = /** @type {string} */ (prop).slice(0, slashIdx);
287
+ let propName = /** @type {string} */ (prop).slice(slashIdx + 1);
288
+ if (!PubSub.pendingDeps.has(ctxName)) {
289
+ PubSub.pendingDeps.set(ctxName, []);
290
+ }
291
+ PubSub.pendingDeps.get(ctxName).push(() => {
292
+ let ctx = PubSub.getCtx(ctxName, false);
293
+ if (!ctx) return;
294
+ let sub = ctx.sub(propName, subCb, init);
295
+ if (sub) {
296
+ this.allSubs.add(sub);
297
+ }
298
+ });
299
+ }
300
+ return;
301
+ }
279
302
  if (!parsed.ctx.has(parsed.name)) {
280
303
  // Avoid *prop binding race:
281
304
  window.queueMicrotask(() => {
@@ -289,12 +312,14 @@ export class Symbiote extends HTMLElement {
289
312
  /** @param {String} prop */
290
313
  notify(prop) {
291
314
  let parsed = Symbiote.#parseProp(prop, this);
315
+ if (!parsed) return;
292
316
  parsed.ctx.notify(parsed.name);
293
317
  }
294
318
 
295
319
  /** @param {String} prop */
296
320
  has(prop) {
297
321
  let parsed = Symbiote.#parseProp(prop, this);
322
+ if (!parsed) return false;
298
323
  return parsed.ctx.has(parsed.name);
299
324
  }
300
325
 
@@ -306,6 +331,7 @@ export class Symbiote extends HTMLElement {
306
331
  */
307
332
  add(prop, val, rewrite = false) {
308
333
  let parsed = Symbiote.#parseProp(prop, this);
334
+ if (!parsed) return;
309
335
  parsed.ctx.add(parsed.name, val, rewrite);
310
336
  }
311
337
 
@@ -330,8 +356,9 @@ export class Symbiote extends HTMLElement {
330
356
  if (first !== 42 && first !== 94 && first !== 64 && first !== 43 && first !== 45 && !prop.includes('/')) {
331
357
  this.localCtx.pub(prop, val);
332
358
  } else {
333
- let parsed = Symbiote.#parseProp(prop, this);
334
- parsed.ctx.pub(parsed.name, val);
359
+ let parsed = Symbiote.#parseProp(prop, this);
360
+ if (!parsed) return true;
361
+ parsed.ctx.pub(parsed.name, val);
335
362
  }
336
363
  return true;
337
364
  },
@@ -341,6 +368,7 @@ export class Symbiote extends HTMLElement {
341
368
  return this.localCtx.read(prop);
342
369
  }
343
370
  let parsed = Symbiote.#parseProp(prop, this);
371
+ if (!parsed) return undefined;
344
372
  return parsed.ctx.read(parsed.name);
345
373
  },
346
374
  });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@symbiotejs/symbiote",
4
- "version": "3.4.5",
4
+ "version": "3.4.7",
5
5
  "description": "Symbiote.js - zero-dependency close-to-platform frontend library to build super-powered web components",
6
6
  "author": "team@rnd-pro.com",
7
7
  "license": "MIT",
@@ -1 +1 @@
1
- {"version":3,"file":"Symbiote.d.ts","sourceRoot":"","sources":["../../core/Symbiote.js"],"names":[],"mappings":";;AAmBA,sBADc,CAAC;IAuBb,cADW,mBAAmB,CACjB;IAGb,sCAAwB;IAExB,iCAGC;IAED,8BAEC;IAkBD,wBAAgB;IA0JhB,+BAJwB,CAAC,SAAZ,aAAU,uBAEZ,CAAC;;;MAuCX;IAmPD,qCAA+B;IAoC/B,iDAFa,OAAO,QAAQ,CAqB3B;IAED,wBAKC;IAGD;;aAOC;IAsHD,6BADY,SAAS,aAAa,QAOjC;IAGD,+BADY,SAAS,aAAa,QAOjC;IAGD,8BADY,SAAS,aAAa,EAIjC;IAGD,gCADY,SAAS,aAAa,EAIjC;IAnjBD,cA6BC;IArID,gCAEC;IAED,qBAAiB;IACjB,uBAAmB;IAiBnB,kBAHW,SAAS,gBAAgB,0BAmFnC;IApDG,aAAiD;IAyDnD,OADW,CAAC,CACoB;IAEhC;;MAAmC;IAEnC,oBADW,GAAG,CAAC,CAAC,EAAE,EAAE,gBAAgB,gBAAW,EAAE,KAAK,eAAU,KAAK,IAAI,CAAC,CACvC;IAEnC;;MAA8B;IAC9B,kBAAwB;IAExB,qBAAwB;IAExB,sBAAyB;IAEzB,wBAA0B;IAE1B,0BAA6B;IAI7B,iBAAoB;IAEpB,6BAAgC;IAEhC,mBAAsB;IAEtB,4BAA8B;IAIhC,yBAEC;IAGD,sBASC;IAGD,4BAKC;IAGD,6BAEC;IAoDD,IALuB,CAAC,SAAX,MAAO,CAAE,QACX,CAAC,WACD,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,wBAmB/B;IAGD,2BAGC;IAGD,uBAGC;IAQD,IALuB,CAAC,SAAX,MAAO,CAAE,qBAEX,CAAC,CAAC,CAAC,CAAC,2BAMd;IAMD,UAHW,OAAO,CAAC,CAAC,CAAC,2BAOpB;IAGD,SADc,CAAC,CA2Bd;IAMD,YAHW,OAAO,CAAC,CAAC,CAAC,mCAcpB;IAED,8BAgBC;IAdG,4CASE;IAwFF,0BAAwC;IAwB1C,uBAAyB;IAG3B,0BAEC;IAED,wBAAoB;IAUpB,yBAAuB;IACvB,6BA0BC;IA6CD,oEAeC;IAMD,yDAoBC;IAYD,0BAME;IAMF,0CAFW,GAAG,QAmBb;IAED,yBAGC;IAOD,8EAmBC;;CA+BF;;mBAntBkB,aAAa;qBACX,iBAAiB;2BACX,iBAAiB"}
1
+ {"version":3,"file":"Symbiote.d.ts","sourceRoot":"","sources":["../../core/Symbiote.js"],"names":[],"mappings":";;AAmBA,sBADc,CAAC;IAuBb,cADW,mBAAmB,CACjB;IAGb,sCAAwB;IAExB,iCAGC;IAED,8BAEC;IAkBD,wBAAgB;IA0JhB,+BAJwB,CAAC,SAAZ,aAAU,uBAEZ,CAAC;;;MA0CX;IA4QD,qCAA+B;IAoC/B,iDAFa,OAAO,QAAQ,CAqB3B;IAED,wBAKC;IAGD;;aAOC;IAsHD,6BADY,SAAS,aAAa,QAOjC;IAGD,+BADY,SAAS,aAAa,QAOjC;IAGD,8BADY,SAAS,aAAa,EAIjC;IAGD,gCADY,SAAS,aAAa,EAIjC;IA/kBD,cA6BC;IArID,gCAEC;IAED,qBAAiB;IACjB,uBAAmB;IAiBnB,kBAHW,SAAS,gBAAgB,0BAmFnC;IApDG,aAAiD;IAyDnD,OADW,CAAC,CACoB;IAEhC;;MAAmC;IAEnC,oBADW,GAAG,CAAC,CAAC,EAAE,EAAE,gBAAgB,gBAAW,EAAE,KAAK,eAAU,KAAK,IAAI,CAAC,CACvC;IAEnC;;MAA8B;IAC9B,kBAAwB;IAExB,qBAAwB;IAExB,sBAAyB;IAEzB,wBAA0B;IAE1B,0BAA6B;IAI7B,iBAAoB;IAEpB,6BAAgC;IAEhC,mBAAsB;IAEtB,4BAA8B;IAIhC,yBAEC;IAGD,sBASC;IAGD,4BAKC;IAGD,6BAEC;IAuDD,IALuB,CAAC,SAAX,MAAO,CAAE,QACX,CAAC,WACD,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,wBAuC/B;IAGD,2BAIC;IAGD,uBAIC;IAQD,IALuB,CAAC,SAAX,MAAO,CAAE,qBAEX,CAAC,CAAC,CAAC,CAAC,2BAOd;IAMD,UAHW,OAAO,CAAC,CAAC,CAAC,2BAOpB;IAGD,SADc,CAAC,CA6Bd;IAMD,YAHW,OAAO,CAAC,CAAC,CAAC,mCAcpB;IAED,8BAgBC;IAdG,4CASE;IAwFF,0BAAwC;IAwB1C,uBAAyB;IAG3B,0BAEC;IAED,wBAAoB;IAUpB,yBAAuB;IACvB,6BA0BC;IA6CD,oEAeC;IAMD,yDAoBC;IAYD,0BAME;IAMF,0CAFW,GAAG,QAmBb;IAED,yBAGC;IAOD,8EAmBC;;CA+BF;;mBA/uBkB,aAAa;qBACX,iBAAiB;2BACX,iBAAiB"}