@symbiote-native/svelte 3.0.3 → 3.0.4

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.
@@ -12,8 +12,7 @@
12
12
  //
13
13
  // This file authors the raw `scroll-view` intrinsic directly, and needs to: it walks an indexable
14
14
  // `plan.cells` list rather than taking an opaque children Snippet, so it can mark sticky cells
15
- // itself. (There is no ScrollView component to render instead — it was deleted 2026-09-10 and an
16
- // app writes the tag too.)
15
+ // itself. (There is no ScrollView component to render instead — an app writes the tag too.)
17
16
  //
18
17
  // It does NOT author the CONTENT node. `registerScrollViewBehavior()` puts a `buildStructure` on
19
18
  // the scroll tags, and exactly one thing may build `RCTScrollContentView` — emitting one here as
@@ -63,12 +63,9 @@
63
63
  Platform.OS,
64
64
  ),
65
65
  );
66
- // DIAGNOSTIC (2026-08-13, tracking why stickyHeaderIndices comes back undefined on Android
67
- // despite the demo passing the bare `stickySectionHeadersEnabled` shorthand): the previous
68
- // logging only showed the RESULT (VirtualizedList's own dlog), never the INPUTS this $derived
69
- // actually read — isolated verification proved bare-shorthand forwarding through this exact
70
- // two-hop generic-component chain works correctly in a standalone repro, so this must show
71
- // what differs in the real component tree.
66
+ // Diagnostic: logs every INPUT this $derived reads, not just VirtualizedList's own result —
67
+ // `stickyHeaderIndices` can come back undefined on Android with the bare
68
+ // `stickySectionHeadersEnabled` shorthand, and only the inputs show what differs.
72
69
  $effect(() => {
73
70
  dlog(
74
71
  `VirtualizedSectionList sticky-inputs enabled=${String(props.stickySectionHeadersEnabled)} ` +
@@ -1,9 +1,6 @@
1
- // Portal — the Svelte adapter's same-surface portal: the twin of React's `createPortal`
2
- // (adapters/react/src/create-portal/index.ts), Solid's `<Portal mount={…}>`
3
- // (adapters/solid/src/create-portal/index.tsx) and Angular's PortalDirective/PortalOutletDirective
4
- // pair. This adapter shipped `createTunnel` and no portal in any spelling until 2026-08-20; the
5
- // two do NOT overlap (see the table at the bottom of this header), so the tunnel was never a
6
- // substitute.
1
+ // Portal — the Svelte adapter's same-surface portal: the twin of React's `createPortal`, Solid's
2
+ // `<Portal mount={…}>` and Angular's PortalDirective/PortalOutletDirective pair. Does NOT overlap
3
+ // with `createTunnel` (table at the bottom of this header) — the tunnel is not a substitute.
7
4
  //
8
5
  // WHY IT IS A COMPONENT (`<Portal mount={…}>`) AND NOT A CALL (`createPortal(content, target)`).
9
6
  // NOT for Solid's reason. Solid had to avoid the call form because Solid evaluates JSX eagerly at
@@ -2,9 +2,8 @@
2
2
  // (svelte-adapter-dom-shim skill §2, §3a, §6). Must run before `mount()` (§3f) — not
3
3
  // necessarily before `svelte` is imported.
4
4
  //
5
- // Single-root only, by design (§10, decided during Svelte adapter planning 2026-08-11): one
6
- // Symbiote app = one process = one Svelte root, so `restoreGlobals()` needs no ref-counting —
7
- // `unmount()` calls it unconditionally.
5
+ // Single-root only, by design (§10): one Symbiote app = one process = one Svelte root, so
6
+ // `restoreGlobals()` needs no ref-counting — `unmount()` calls it unconditionally.
8
7
  //
9
8
  // Deliberately NOT patched, and must stay that way (§6b, §6c, §6d) — both verified against the
10
9
  // real vendored RN source (.vendors/react-native/packages/react-native/Libraries/Core/), not
@@ -51,20 +50,9 @@ const PATCHED_KEYS = [
51
50
  // with (unlike `navigator`/`requestAnimationFrame`, verified against .vendors/react-native —
52
51
  // see the header comment above), so patching this is safe.
53
52
  //
54
- // `get()` returns a TRUTHY stand-in, and that is the whole reason `set_custom_element_data` can be
55
- // made lossless. Its condition (attributes.js:245-265) is a ternary, not a fallback:
56
- //
57
- // setters_cache.has(nodeName) || !customElements || customElements.get(nodeName)
58
- // ? get_setters(node).includes(prop) <- a real setter decides; the value passes through
59
- // : value && typeof value === 'object' <- a HEURISTIC: an object is set as a property and
60
- // every scalar is handed on as String(value)
61
- //
62
- // Returning `undefined` — which it did until 2026-09-07 — selects the heuristic, so
63
- // `<text-input multiline={false}>` committed the STRING "false" and an object-valued prop with no
64
- // prototype setter was assigned to a plain JS property and silently lost. Anything truthy steers
65
- // it to `get_setters`, which reaches `ShimElement.prototype`'s accessors (see
66
- // `svelte-shim-element-global-must-be-an-ancestor.md` for why that walk terminates where it does).
67
- // One reader in the whole client runtime, so nothing else is affected.
53
+ // `get()` returns a TRUTHY stand-in — the whole reason `set_custom_element_data` stays lossless.
54
+ // Falsy selects attributes.js's HEURISTIC path instead of `get_setters`: it stringifies scalars
55
+ // and drops any object-valued prop with no prototype setter.
68
56
  const FAKE_CUSTOM_ELEMENT_REGISTRY = {
69
57
  get: () => ShimElement,
70
58
  };
package/build/index.js CHANGED
@@ -4,11 +4,9 @@
4
4
  // All Fabric clone-on-write lives in the engine, shared cross-adapter. App code names only
5
5
  // @symbiote-native/svelte.
6
6
  //
7
- // Full component parity with React/Vue/Angular landed 2026-08-11 (svelte-adapter-dom-shim
8
- // skill §15): every `core/components` render function has a fixed tree shape, so no
9
- // `descriptorToSvelte` bridge was ever needed — each component below is hand-authored Svelte
10
- // markup mirroring its render-*.ts, reusing only the pure state/render logic. See skill §17/§18
11
- // for the one open async-exception repro and the honest cross-cutting gap list.
7
+ // Full component parity with React/Vue/Angular (svelte-adapter-dom-shim skill §15): every
8
+ // `core/components` render function has a fixed tree shape, so no `descriptorToSvelte` bridge is
9
+ // needed — each component below is hand-authored Svelte markup mirroring its render-*.ts.
12
10
  // Bare side-effect import, deliberately NOT a re-export and deliberately not beside one of the
13
11
  // same specifier: it registers the press behavior with the engine's host-behavior registry. Any
14
12
  // other shape is dropped by Metro's inlineRequires in a release build — see register.ts.
@@ -25,9 +23,8 @@ export { KeyboardAvoidingView, Modal, VirtualizedList, FlatList, VirtualizedSect
25
23
  // threaded through this barrel (parity fix, see React's index.ts lines 55-58, 89, 245-250).
26
24
  export { setImageSourceResolver } from '@symbiote-native/components';
27
25
  // Pure, framework-agnostic runtime modules — same re-export every other adapter does per
28
- // CLAUDE.md's <runtime_modules_layering>. PanResponder was missing here (present on
29
- // React/Vue's own barrels) until 2026-08-12 — a pure engine re-export, no framework glue, so
30
- // adding it is a one-line parity fix, not new adapter work.
26
+ // CLAUDE.md's <runtime_modules_layering>. A pure engine re-export with no framework glue, so
27
+ // adding one is a one-line parity fix, not new adapter work.
31
28
  export { Platform, StyleSheet, PlatformColor, DynamicColorIOS, processColor, setNativeViewConfigSource, setColorProcessor, setDeviceEventSource, PixelRatio, PanResponder, dlog, isDebug, } from '@symbiote-native/engine';
32
29
  // The two namespaces left behind by primitives that became tags, here rather than in the component
33
30
  // block above for one reason: they carry no view. `Image` gets an adapter file only because it
@@ -9,10 +9,9 @@
9
9
  // between the value graph and the node's Fabric tag, and both of those were already engine-side.
10
10
  //
11
11
  // Those three were aliases of the wrappers, and the wrappers are gone — a primitive is a tag now,
12
- // which is not a value `<Animated.X>` can call. `Animated.ScrollView` left the same way on
13
- // 2026-09-10: `bindAnimatedEvent` (node.ts, from `setEventListener`) attaches a native-driven event
14
- // on ANY host node, which was the one job a scroll wrapper still looked like it had. The whole API
15
- // is `<scroll-view style={{ opacity: v }} p={{ onScroll: Animated.event(…) }}>`.
12
+ // which is not a value `<Animated.X>` can call. `Animated.ScrollView` left the same way:
13
+ // `bindAnimatedEvent` (node.ts) attaches a native-driven event on ANY host node.
14
+ // The whole API is `<scroll-view style={{ opacity: v }} p={{ onScroll: Animated.event(…) }}>`.
16
15
  //
17
16
  // The two below REMAIN because the LIST family is tier 3: a render prop decides their output shape
18
17
  // in JS, so there is no tag for `<Animated.X>` to be an alias of.
@@ -1,11 +1,8 @@
1
1
  // svelte-adapter-dom-shim skill §16: Svelte trims only the leading/trailing whitespace of a
2
2
  // fragment's own children - never whitespace INSIDE a single Text node, and never a
3
- // whitespace-only Text node BETWEEN two siblings. Vue's compiler (and every browser) collapses
4
- // both; Svelte doesn't. Confirmed against the real compiler (2026-08-17): a Text node authored
5
- // as `Hello world, this is a\n long sentence.` compiles verbatim into
6
- // `$.text('Hello world, this is a\n long sentence.')` - the newline and indent ship into the
7
- // native text content and render as a forced line break plus stray leading spaces on device.
8
- // Reproduced live on an iOS simulator before this file existed; fixed with it registered.
3
+ // whitespace-only Text node BETWEEN two siblings. Vue's compiler (and every browser) collapse both.
4
+ // A Text node authored as `Hello world, this is a\n long sentence.` compiles verbatim, so the
5
+ // newline and indent ship into native text as a forced line break plus stray leading spaces.
9
6
  //
10
7
  // Two hazards:
11
8
  // 1. Wrapped sentence - a Text node with real content plus an embedded whitespace run
@@ -1,4 +1,4 @@
1
- // §7 of svelte-adapter-dom-shim (DECIDED 2026-08-11): the constructs that compile cleanly and
1
+ // §7 of svelte-adapter-dom-shim: the constructs that compile cleanly and
2
2
  // then silently do nothing under the DOM shim. Everything else in the original §4 table is
3
3
  // already closed by "app code can't reach it" or "the TS/Svelte compiler already errors on it for
4
4
  // free" (see the skill for the full reachability table). This preprocessor is the guard for what
@@ -127,13 +127,11 @@ export function scopedStyles() {
127
127
  // ---------------------------------------------------------------------------------------------
128
128
  // The <style> block, located WITHOUT parsing it.
129
129
  //
130
- // This is svelte's own tag regex (src/compiler/preprocess/index.js), which is what its official
131
- // `preprocess()` style hook uses to hand a block's content to a preprocessor unparsed — and the
132
- // reason `svelte-preprocess` can compile SCSS at all. Reading `parse().css` instead, as this file
133
- // did until 2026-08-20, validates the block as CSS whatever `lang` says: `<style lang="scss">$pad:
134
- // 7px;</style>` threw `css_expected_identifier` before the language table above was ever
135
- // consulted, so only SCSS that is already valid CSS (nesting) survived. A `<!-- -->` comment is an
136
- // alternative of the pattern purely so a commented-out block is skipped rather than matched.
130
+ // This is svelte's own tag regex (src/compiler/preprocess/index.js): what its official
131
+ // `preprocess()` style hook uses to hand a block's content unparsed, the reason `svelte-preprocess`
132
+ // can compile SCSS at all — `parse().css` would validate it as CSS whatever `lang` says.
133
+ // A `<!-- -->` comment is an alternative of the pattern purely so a commented-out block is
134
+ // skipped rather than matched.
137
135
  const STYLE_TAG_PATTERN = /<!--[^]*?-->|<style((?:\s+[^=>'"/\s]+=(?:"[^"]*"|'[^']*'|[^>\s]+)|\s+[^=>'"/\s]+)*\s*)(?:\/>|>([\S\s]*?)<\/style>)/g;
138
136
  const LANG_ATTRIBUTE_PATTERN = /\blang\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>]+))/;
139
137
  function findStyleBlock(content) {
package/build/render.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // Mount a Svelte app onto a Fabric surface. The native host hands us a rootTag; we create a
2
2
  // surface for it, install the DOM shim, and let stock compiled Svelte output drive it while
3
- // believing it is talking to the real DOM. Decided during Svelte adapter planning
4
- // (2026-08-11, svelte-adapter-dom-shim skill §10): single root per process, so
3
+ // believing it is talking to the real DOM.
4
+ // Single root per process (svelte-adapter-dom-shim skill §10), so
5
5
  // patchGlobals()/restoreGlobals() need no ref-counting.
6
6
  import { mount as svelteMount, unmount as svelteUnmount, } from 'svelte';
7
7
  import { createSurface, disposeRoot, dlog, reportUncaughtError, } from '@symbiote-native/engine';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@symbiote-native/svelte",
3
- "version": "3.0.3",
3
+ "version": "3.0.4",
4
4
  "description": "SymbioteNative's Svelte adapter — a DOM shim over stock compiled Svelte output driving real native iOS/Android views through the same engine as every other adapter.",
5
5
  "keywords": [
6
6
  "react-native",
@@ -73,22 +73,22 @@
73
73
  },
74
74
  "dependencies": {
75
75
  "typescript": "~6.0.0",
76
- "@symbiote-native/components": "3.1.1",
77
- "@symbiote-native/css-parser": "0.5.1"
76
+ "@symbiote-native/components": "3.1.2",
77
+ "@symbiote-native/css-parser": "0.5.2"
78
78
  },
79
79
  "peerDependencies": {
80
80
  "svelte": ">=5.56.0",
81
81
  "react-native": ">=0.86",
82
- "@symbiote-native/engine": "^1.3.0"
82
+ "@symbiote-native/engine": "^1.3.1"
83
83
  },
84
84
  "devDependencies": {
85
85
  "@vue/runtime-core": "^3.5.13",
86
86
  "react": "19.2.3",
87
87
  "svelte": "^5.56.0",
88
- "@symbiote-native/engine": "1.3.0",
89
- "@symbiote-native/react": "3.0.3",
90
- "@symbiote-native/test-utils": "0.4.3",
91
- "@symbiote-native/vue": "3.0.3"
88
+ "@symbiote-native/engine": "1.3.1",
89
+ "@symbiote-native/react": "3.0.4",
90
+ "@symbiote-native/test-utils": "0.4.4",
91
+ "@symbiote-native/vue": "3.0.4"
92
92
  },
93
93
  "scripts": {
94
94
  "typecheck": "tsc --build",