@symbiote-native/solid 3.2.0 → 3.4.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.
Files changed (64) hide show
  1. package/build/components/flat-list/index.d.ts +3 -2
  2. package/build/components/flat-list/index.jsx +8 -10
  3. package/build/components/input-accessory-view-props.d.ts +4 -4
  4. package/build/components/keyboard-avoiding-view.d.ts +2 -2
  5. package/build/components/keyboard-avoiding-view.jsx +34 -114
  6. package/build/components/layout-conformance-props.d.ts +6 -0
  7. package/build/components/layout-conformance-props.js +1 -0
  8. package/build/components/modal.d.ts +4 -4
  9. package/build/components/modal.jsx +11 -11
  10. package/build/components/refresh-control-props.d.ts +7 -7
  11. package/build/components/scroll-view-props.d.ts +8 -5
  12. package/build/components/text-input-props.d.ts +2 -1
  13. package/build/components/text-props.d.ts +3 -3
  14. package/build/components/touchable-props.d.ts +6 -6
  15. package/build/components/virtualized-list/index.android.d.ts +2 -2
  16. package/build/components/virtualized-list/index.ios.d.ts +2 -2
  17. package/build/components/virtualized-list/item-content.d.ts +6 -0
  18. package/build/components/virtualized-list/item-content.jsx +9 -0
  19. package/build/components/virtualized-list/list-body.d.ts +15 -0
  20. package/build/components/virtualized-list/list-body.jsx +20 -0
  21. package/build/components/virtualized-list/list-parts.d.ts +14 -0
  22. package/build/components/virtualized-list/list-parts.js +27 -0
  23. package/build/components/virtualized-list/list-rows.d.ts +18 -0
  24. package/build/components/virtualized-list/list-rows.jsx +91 -0
  25. package/build/components/virtualized-list/list-window.d.ts +11 -0
  26. package/build/components/virtualized-list/list-window.js +29 -0
  27. package/build/components/virtualized-list/nested-scope.d.ts +7 -0
  28. package/build/components/virtualized-list/nested-scope.js +21 -0
  29. package/build/components/virtualized-list/scroll-handlers.d.ts +12 -0
  30. package/build/components/virtualized-list/scroll-handlers.js +31 -0
  31. package/build/components/virtualized-list/scroll-tree.d.ts +18 -0
  32. package/build/components/virtualized-list/scroll-tree.jsx +143 -0
  33. package/build/components/virtualized-list/shared.d.ts +3 -74
  34. package/build/components/virtualized-list/shared.jsx +53 -752
  35. package/build/components/virtualized-list/sticky-binding.d.ts +13 -0
  36. package/build/components/virtualized-list/sticky-binding.js +111 -0
  37. package/build/components/virtualized-list/sticky-header.d.ts +1 -0
  38. package/build/components/virtualized-list/sticky-header.jsx +11 -159
  39. package/build/components/virtualized-list/sticky-state.d.ts +14 -0
  40. package/build/components/virtualized-list/sticky-state.js +54 -0
  41. package/build/components/virtualized-list/use-list-driver.d.ts +22 -0
  42. package/build/components/virtualized-list/use-list-driver.js +128 -0
  43. package/build/components/virtualized-list/use-separators.d.ts +7 -0
  44. package/build/components/virtualized-list/use-separators.js +22 -0
  45. package/build/components/virtualized-list/virtualized-list-props.d.ts +86 -0
  46. package/build/components/virtualized-list/virtualized-list-props.js +53 -0
  47. package/build/components/virtualized-section-list/index.d.ts +22 -9
  48. package/build/components/virtualized-section-list/index.jsx +87 -115
  49. package/build/components/virtualized-section-list/section-item-cell.d.ts +18 -0
  50. package/build/components/virtualized-section-list/section-item-cell.jsx +37 -0
  51. package/build/components.d.ts +5 -1
  52. package/build/components.js +1 -0
  53. package/build/index.d.ts +10 -4
  54. package/build/index.js +21 -37
  55. package/build/modules/animated/index.d.ts +54 -41
  56. package/build/modules/animated/index.js +2 -26
  57. package/build/modules/app-registry/index.d.ts +3 -3
  58. package/build/modules/app-registry/index.js +2 -2
  59. package/build/modules/status-bar.js +14 -27
  60. package/build/primitives/create-color-scheme.d.ts +1 -1
  61. package/build/render.js +16 -28
  62. package/build/root-tag-context.d.ts +1 -0
  63. package/build/root-tag-context.js +4 -0
  64. package/package.json +6 -6
@@ -1,56 +1,69 @@
1
- import { AnimatedValue, AnimatedValueXY, AnimatedColor, timing, spring, decay, parallel, sequence, stagger, loop, delay, add, subtract, multiply, divide, modulo, diffClamp, event, forkEvent, unforkEvent } from '@symbiote-native/engine';
2
1
  import { createAnimatedComponent } from './create-animated-component';
3
2
  export { createAnimatedComponent } from './create-animated-component';
4
3
  export type { IAnimatedComponentProps } from './create-animated-component';
5
4
  export { AnimatedProps, AnimatedStyle, AnimatedTransform, } from '@symbiote-native/engine';
6
5
  type IAnimatedComponent = ReturnType<typeof createAnimatedComponent>;
7
6
  export declare const Animated: {
8
- Value: typeof AnimatedValue;
9
- ValueXY: typeof AnimatedValueXY;
10
- Color: typeof AnimatedColor;
7
+ timing: {
8
+ (value: import("@symbiote-native/engine").AnimatedValue, config: import("@symbiote-native/engine").ITimingConfig): import("@symbiote-native/engine").ICompositeAnimation;
9
+ (value: import("@symbiote-native/engine").IVectorValue, config: import("@symbiote-native/engine").IVectorTimingConfig): import("@symbiote-native/engine").ICompositeAnimation;
10
+ };
11
+ spring: {
12
+ (value: import("@symbiote-native/engine").AnimatedValue, config: import("@symbiote-native/engine").ISpringConfig): import("@symbiote-native/engine").ICompositeAnimation;
13
+ (value: import("@symbiote-native/engine").IVectorValue, config: import("@symbiote-native/engine").IVectorSpringConfig): import("@symbiote-native/engine").ICompositeAnimation;
14
+ };
15
+ decay: (_value: import("@symbiote-native/engine").AnimatedValue, _config: import("@symbiote-native/engine").IDecayConfig) => import("@symbiote-native/engine").ICompositeAnimation;
16
+ parallel: (animations: import("@symbiote-native/engine").ICompositeAnimation[], _config?: import("@symbiote-native/engine").IParallelConfig) => import("@symbiote-native/engine").ICompositeAnimation;
17
+ sequence: (animations: import("@symbiote-native/engine").ICompositeAnimation[]) => import("@symbiote-native/engine").ICompositeAnimation;
18
+ stagger: (_time: number, animations: import("@symbiote-native/engine").ICompositeAnimation[]) => import("@symbiote-native/engine").ICompositeAnimation;
19
+ loop: (_animation: import("@symbiote-native/engine").ICompositeAnimation) => import("@symbiote-native/engine").ICompositeAnimation;
20
+ delay: (_time: number) => import("@symbiote-native/engine").ICompositeAnimation;
21
+ Value: typeof import("@symbiote-native/engine").AnimatedValue;
22
+ ValueXY: typeof import("@symbiote-native/engine").AnimatedValueXY;
23
+ Color: typeof import("@symbiote-native/engine").AnimatedColor;
24
+ Interpolation: typeof import("@symbiote-native/engine").AnimatedInterpolation;
25
+ Node: typeof import("@symbiote-native/engine").AnimatedNode;
11
26
  Easing: import("@symbiote-native/engine").IEasing;
12
- timing: typeof timing;
13
- spring: typeof spring;
14
- decay: typeof decay;
15
- parallel: typeof parallel;
16
- sequence: typeof sequence;
17
- stagger: typeof stagger;
18
- loop: typeof loop;
19
- delay: typeof delay;
20
- add: typeof add;
21
- subtract: typeof subtract;
22
- multiply: typeof multiply;
23
- divide: typeof divide;
24
- modulo: typeof modulo;
25
- diffClamp: typeof diffClamp;
26
- event: typeof event;
27
- forkEvent: typeof forkEvent;
28
- unforkEvent: typeof unforkEvent;
27
+ add: typeof import("@symbiote-native/engine").add;
28
+ subtract: typeof import("@symbiote-native/engine").subtract;
29
+ multiply: typeof import("@symbiote-native/engine").multiply;
30
+ divide: typeof import("@symbiote-native/engine").divide;
31
+ modulo: typeof import("@symbiote-native/engine").modulo;
32
+ diffClamp: typeof import("@symbiote-native/engine").diffClamp;
33
+ event: typeof import("@symbiote-native/engine").event;
34
+ attachNativeEvent: typeof import("@symbiote-native/engine").attachNativeEvent;
35
+ forkEvent: typeof import("@symbiote-native/engine").forkEvent;
36
+ unforkEvent: typeof import("@symbiote-native/engine").unforkEvent;
37
+ Event: typeof import("@symbiote-native/engine").AnimatedEvent;
29
38
  FlatList: IAnimatedComponent;
30
39
  SectionList: IAnimatedComponent;
31
40
  createAnimatedComponent: typeof createAnimatedComponent;
32
41
  } | {
33
- Value: typeof AnimatedValue;
34
- ValueXY: typeof AnimatedValueXY;
35
- Color: typeof AnimatedColor;
42
+ Value: typeof import("@symbiote-native/engine").AnimatedValue;
43
+ ValueXY: typeof import("@symbiote-native/engine").AnimatedValueXY;
44
+ Color: typeof import("@symbiote-native/engine").AnimatedColor;
45
+ Interpolation: typeof import("@symbiote-native/engine").AnimatedInterpolation;
46
+ Node: typeof import("@symbiote-native/engine").AnimatedNode;
36
47
  Easing: import("@symbiote-native/engine").IEasing;
37
- timing: (value: AnimatedValue, config: import("@symbiote-native/engine").ITimingConfig) => import("@symbiote-native/engine").ICompositeAnimation;
38
- spring: (value: AnimatedValue, config: import("@symbiote-native/engine").ISpringConfig) => import("@symbiote-native/engine").ICompositeAnimation;
39
- decay: (_value: AnimatedValue, _config: import("@symbiote-native/engine").IDecayConfig) => import("@symbiote-native/engine").ICompositeAnimation;
40
- parallel: (animations: import("@symbiote-native/engine").ICompositeAnimation[], _config?: import("@symbiote-native/engine").IParallelConfig) => import("@symbiote-native/engine").ICompositeAnimation;
41
- sequence: (animations: import("@symbiote-native/engine").ICompositeAnimation[]) => import("@symbiote-native/engine").ICompositeAnimation;
42
- stagger: (_time: number, animations: import("@symbiote-native/engine").ICompositeAnimation[]) => import("@symbiote-native/engine").ICompositeAnimation;
43
- loop: (_animation: import("@symbiote-native/engine").ICompositeAnimation) => import("@symbiote-native/engine").ICompositeAnimation;
44
- delay: (_time: number) => import("@symbiote-native/engine").ICompositeAnimation;
45
- add: typeof add;
46
- subtract: typeof subtract;
47
- multiply: typeof multiply;
48
- divide: typeof divide;
49
- modulo: typeof modulo;
50
- diffClamp: typeof diffClamp;
51
- event: typeof event;
52
- forkEvent: typeof forkEvent;
53
- unforkEvent: typeof unforkEvent;
48
+ timing: typeof import("@symbiote-native/engine").timing;
49
+ spring: typeof import("@symbiote-native/engine").spring;
50
+ decay: typeof import("@symbiote-native/engine").decay;
51
+ parallel: typeof import("@symbiote-native/engine").parallel;
52
+ sequence: typeof import("@symbiote-native/engine").sequence;
53
+ stagger: typeof import("@symbiote-native/engine").stagger;
54
+ loop: typeof import("@symbiote-native/engine").loop;
55
+ delay: typeof import("@symbiote-native/engine").delay;
56
+ add: typeof import("@symbiote-native/engine").add;
57
+ subtract: typeof import("@symbiote-native/engine").subtract;
58
+ multiply: typeof import("@symbiote-native/engine").multiply;
59
+ divide: typeof import("@symbiote-native/engine").divide;
60
+ modulo: typeof import("@symbiote-native/engine").modulo;
61
+ diffClamp: typeof import("@symbiote-native/engine").diffClamp;
62
+ event: typeof import("@symbiote-native/engine").event;
63
+ attachNativeEvent: typeof import("@symbiote-native/engine").attachNativeEvent;
64
+ forkEvent: typeof import("@symbiote-native/engine").forkEvent;
65
+ unforkEvent: typeof import("@symbiote-native/engine").unforkEvent;
66
+ Event: typeof import("@symbiote-native/engine").AnimatedEvent;
54
67
  FlatList: IAnimatedComponent;
55
68
  SectionList: IAnimatedComponent;
56
69
  createAnimatedComponent: typeof createAnimatedComponent;
@@ -19,7 +19,7 @@
19
19
  // useNativeDriver animation promotes the value graph itself (animations/base.ts ->
20
20
  // value.__startNativeAnimation -> graph.__makeNative), and the props leaf follows automatically
21
21
  // through graph.__addChild. This file only assembles the surface.
22
- import { AnimatedValue, AnimatedValueXY, AnimatedColor, AnimatedMock, Easing, Platform, timing, spring, decay, parallel, sequence, stagger, loop, delay, add, subtract, multiply, divide, modulo, diffClamp, event, forkEvent, unforkEvent, } from '@symbiote-native/engine';
22
+ import { AnimatedDrivers, AnimatedMock, Platform, } from '@symbiote-native/engine';
23
23
  import { FlatList } from '../../components/flat-list/index.jsx';
24
24
  import { SectionList } from '../../components/section-list/index.jsx';
25
25
  import { createAnimatedComponent } from './create-animated-component.jsx';
@@ -29,35 +29,11 @@ export { createAnimatedComponent } from './create-animated-component.jsx';
29
29
  export { AnimatedProps, AnimatedStyle, AnimatedTransform, } from '@symbiote-native/engine';
30
30
  let animatedFlatList;
31
31
  let animatedSectionList;
32
- // The live, JS-driven driver half. RN's AnimatedImplementation.
33
- const liveDrivers = {
34
- Value: AnimatedValue,
35
- ValueXY: AnimatedValueXY,
36
- Color: AnimatedColor,
37
- Easing,
38
- timing,
39
- spring,
40
- decay,
41
- parallel,
42
- sequence,
43
- stagger,
44
- loop,
45
- delay,
46
- add,
47
- subtract,
48
- multiply,
49
- divide,
50
- modulo,
51
- diffClamp,
52
- event,
53
- forkEvent,
54
- unforkEvent,
55
- };
56
32
  // RN swaps the WHOLE driver namespace for the mock when the host reports isDisableAnimations
57
33
  // (reduced motion / test env): same surface, every animation jumping to its final value with no
58
34
  // frames. The COMPONENTS stay live in both branches — only this half is swapped, exactly as RN
59
35
  // spreads `...Animated` over the same component getters.
60
- const drivers = Platform.isDisableAnimations ? AnimatedMock : liveDrivers;
36
+ const drivers = Platform.isDisableAnimations ? AnimatedMock : AnimatedDrivers;
61
37
  export const Animated = {
62
38
  get FlatList() {
63
39
  animatedFlatList ??= createAnimatedComponent(FlatList);
@@ -1,7 +1,7 @@
1
1
  import type { Component } from 'solid-js';
2
- import { type IAppParameters } from '@symbiote-native/engine';
2
+ import { HeadlessJsTaskError, type IAppParameters } from '@symbiote-native/engine';
3
3
  export type IComponentProvider = () => Component;
4
4
  export type IWrapperComponentProvider = (appParameters: IAppParameters) => Component;
5
5
  declare const AppRegistry: import("@symbiote-native/engine").IAppRegistry<IComponentProvider, IWrapperComponentProvider>, setHostRegistrar: (registrar: import("@symbiote-native/engine").IHostRegistrar) => void;
6
- export { AppRegistry, setHostRegistrar };
7
- export type { IAppParameters, IRunnable, IHostRegistrar, IRegistry, IHeadlessTask, ITaskProvider, ITaskCanceller, ITaskCancelProvider, } from '@symbiote-native/engine';
6
+ export { AppRegistry, HeadlessJsTaskError, setHostRegistrar };
7
+ export type { IAppConfig, IAppParameters, IRunnable, IHostRegistrar, IRegistry, IHeadlessTask, ITaskProvider, ITaskCanceller, ITaskCancelProvider, } from '@symbiote-native/engine';
@@ -8,7 +8,7 @@
8
8
  // design pass: a Solid component is an ordinary function value, so wrapping composes exactly the
9
9
  // way Vue's `h(wrapper, null, { default: renderRoot })` does — `createComponent(Wrapper, { get
10
10
  // children() {…} })`, which is also the literal shape compiled JSX emits for children.
11
- import { createAppRegistry, dlog, } from '@symbiote-native/engine';
11
+ import { createAppRegistry, dlog, HeadlessJsTaskError, } from '@symbiote-native/engine';
12
12
  import { createComponent } from '../../renderer.js';
13
13
  import { mount } from '../../render.js';
14
14
  function runnableFor(componentProvider, getWrapperComponentProvider) {
@@ -34,4 +34,4 @@ function runnableFor(componentProvider, getWrapperComponentProvider) {
34
34
  };
35
35
  }
36
36
  const { AppRegistry, setHostRegistrar } = createAppRegistry(runnableFor);
37
- export { AppRegistry, setHostRegistrar };
37
+ export { AppRegistry, HeadlessJsTaskError, setHostRegistrar };
@@ -1,45 +1,32 @@
1
- // StatusBar — the Solid lifecycle half, and nothing else. The native StatusBarManager driving
2
- // (applyStatusBarProps), the imperative statics (statusBarImperative) and the Android bar-height
3
- // constant all live in @symbiote-native/engine, shared verbatim with React / Vue / Svelte /
4
- // Angular; Metro selects the engine's index.ios.ts / index.android.ts per host, so the platform
5
- // divergence never reaches this file. Solid supplies only the declarative shape: a component that
6
- // renders no Fabric view and re-applies its props from a `createEffect` on mount and on every
7
- // prop change.
8
- //
9
- // FLAT, not a folder: the file-layout rule gives a module its own folder only for real
10
- // `.ios`/`.android`/`-shared` variants. React needs two files because its useEffect dep array is
11
- // written by hand per platform; there is no dep array here, so one file covers both hosts —
12
- // the same shape Svelte's and Angular's StatusBar landed on.
13
- //
14
- // Simplification vs RN, inherited from every other adapter: RN keeps a prop-merge stack so nested
15
- // StatusBars compose (deepest wins); this direct-applies one component's props.
16
- import { createEffect } from 'solid-js';
17
- import { applyStatusBarProps, statusBarImperative, statusBarCurrentHeight, } from '@symbiote-native/engine';
18
- // Renders null: StatusBar owns no host node, it drives a native module.
1
+ // Solid half of StatusBar, the props stack and statics live in the engine. It renders no Fabric
2
+ // view, applies its props to one stack entry from a `createEffect` and releases it on cleanup
3
+ // FLAT, one file covers both hosts since there is no per-platform dependency array
4
+ import { createEffect, onCleanup } from 'solid-js';
5
+ import { createStatusBarEntry, statusBarImperative, statusBarCurrentHeight, } from '@symbiote-native/engine';
6
+ // Renders null: StatusBar owns no host node, it drives a native module
19
7
  function StatusBarComponent(props) {
8
+ const entry = createStatusBarEntry();
20
9
  createEffect(() => {
21
- // Every field is read HERE, not inside the engine, so the effect's dependency set is the whole
22
- // prop surface rather than whichever subset this platform's impl happens to destructure —
23
- // iOS's applyStatusBarProps never touches backgroundColor/translucent, and a props proxy read
24
- // only there would silently stop re-applying after a host swap.
25
- applyStatusBarProps({
10
+ // Every field is read here, so the effect depends on the whole prop surface
11
+ entry.apply({
26
12
  barStyle: props.barStyle,
27
13
  hidden: props.hidden,
28
14
  animated: props.animated,
15
+ showHideTransition: props.showHideTransition,
29
16
  networkActivityIndicatorVisible: props.networkActivityIndicatorVisible,
30
17
  backgroundColor: props.backgroundColor,
31
18
  translucent: props.translucent,
32
19
  });
33
20
  });
21
+ // Popping restores what the stack held below this entry
22
+ onCleanup(() => entry.release());
34
23
  return null;
35
24
  }
36
25
  const StatusBarWithStatics = Object.assign(StatusBarComponent, statusBarImperative);
37
- // Android exposes the bar height as a native constant; undefined on iOS / when absent. A getter,
38
- // not a value, so nothing touches native at import time.
26
+ // A getter, not a value, so nothing touches native at import time
39
27
  Object.defineProperty(StatusBarWithStatics, 'currentHeight', {
40
28
  get: statusBarCurrentHeight,
41
29
  enumerable: true,
42
30
  });
43
- // currentHeight is optional, so the defineProperty-added accessor need not appear on the runtime
44
- // object's inferred type for this assignment to hold (no cast) — same shape as Svelte's.
31
+ // `currentHeight` is optional, so the accessor need not appear on the inferred type (no cast)
45
32
  export const StatusBar = StatusBarWithStatics;
@@ -1,3 +1,3 @@
1
1
  import { type Accessor } from 'solid-js';
2
2
  import { type IColorSchemeName } from '@symbiote-native/engine';
3
- export declare function createColorScheme(): Accessor<IColorSchemeName | null>;
3
+ export declare function createColorScheme(): Accessor<IColorSchemeName | null | undefined>;
package/build/render.js CHANGED
@@ -4,10 +4,10 @@
4
4
  import { createSurface, disposeRoot, dlog, reportUncaughtError, } from '@symbiote-native/engine';
5
5
  import { catchError, createRoot } from 'solid-js';
6
6
  import { createComponent, insert, setActiveSurface } from './renderer.js';
7
- // One Solid root per surface, so a surface can be torn down (unmount) or cleanly re-mounted on the
8
- // same rootTag: the bridgeless host stops and restarts a surface on Fast Refresh and on
9
- // lifecycle/focus changes, reusing the rootTag. The value is Solid's own dispose function — the
10
- // whole reactive root goes with it, effects and cleanups included.
7
+ import { RootTagContext } from './root-tag-context.js';
8
+ // One Solid root per surface, so a surface can be torn down or re-mounted on the same `rootTag`
9
+ // The bridgeless host does that on Fast Refresh and on lifecycle or focus changes
10
+ // The value is Solid's own `dispose`, the whole reactive root goes with it
11
11
  const roots = new Map();
12
12
  // Insertion-ordered, so the last entry is the most recently mounted surface. Kept alongside
13
13
  // `roots` only to answer one question: when a surface is torn down, is there another one still
@@ -21,16 +21,9 @@ function teardown(rootTag) {
21
21
  dispose();
22
22
  roots.delete(rootTag);
23
23
  surfaces.delete(rootTag);
24
- // Cleared AFTER dispose() on purpose: disposing runs user cleanups, which can still mutate the
25
- // tree, and those mutations should reach the surface they belong to rather than be dropped by
26
- // renderer.ts's post-unmount guard.
27
- //
28
- // And cleared ONLY when the surface going away is the one the renderer is actually committing
29
- // into. Clearing unconditionally killed a surface that was still mounted: with two surfaces up,
30
- // unmounting the FIRST left the second alive but permanently uncommitted — every later mutation
31
- // hit renderer.ts's "mutation after unmount" guard and was silently dropped. That is reachable
32
- // from ordinary code the moment two surfaces exist, which is exactly the createTunnel case
33
- // (../create-tunnel): the source surface stops, the target must keep painting.
24
+ // Cleared after `dispose()`, since user cleanups run inside it and can still mutate the tree
25
+ // Cleared only for the surface the renderer commits into, else a live surface goes dead
26
+ // With two surfaces up, unmounting the first must leave the second painting, as `createTunnel`
34
27
  if (activeRootTag !== rootTag) {
35
28
  disposeRoot(rootTag);
36
29
  return;
@@ -47,23 +40,18 @@ export function mount(rootTag, RootComponent) {
47
40
  surfaces.set(rootTag, surface);
48
41
  activeRootTag = rootTag;
49
42
  setActiveSurface(surface);
50
- // `createComponent(RootComponent, {})` is exactly what compiled JSX emits for `<RootComponent />`
51
- // — written by hand here because this file is plain TS, deliberately: render.ts is the one module
52
- // an app's entry point imports before any JSX has been compiled, so keeping it JSX-free means it
53
- // needs no Babel pass of its own.
54
- //
55
- // The surface IS the render container: a top-level insert routes to surface.appendChild
56
- // (renderer.ts's insertNode), and the engine wraps surface.children in its synthetic flex root.
57
- //
58
- // `createRoot` + `insert` IS renderer.ts's `render(code, surface)`, spelled out so `catchError`
59
- // can sit BETWEEN them. Solid's own `render` runs `insert(element, code())` — the insert lands
60
- // outside anything `code` wrapped, so a root component returning a bare accessor would build its
61
- // render effect under an owner with no error handler and throw past this seam. Written this way
62
- // the insert is inside, and every computation the mount creates inherits the handler.
43
+ // `createComponent` is what compiled JSX emits, written by hand: render.ts must stay JSX-free
44
+ // `createRoot` + `insert` is `render()` spelled out, so `catchError` wraps the insert as well
45
+ // The Provider hands the surface tag to `useContext(RootTagContext)` for the whole tree
63
46
  let unwinding;
64
47
  const dispose = createRoot(disposeRootScope => {
65
48
  catchError(() => {
66
- insert(surface, createComponent(RootComponent, {}));
49
+ insert(surface, createComponent(RootTagContext.Provider, {
50
+ value: rootTag,
51
+ get children() {
52
+ return createComponent(RootComponent, {});
53
+ },
54
+ }));
67
55
  }, error => {
68
56
  if (unwinding?.error !== error) {
69
57
  unwinding = { error };
@@ -0,0 +1 @@
1
+ export declare const RootTagContext: import("solid-js").Context<number>;
@@ -0,0 +1,4 @@
1
+ // RN's `RootTagContext`: every `mount` provides the tag of its surface, 0 stays the default
2
+ import { createContext } from 'solid-js';
3
+ const NO_SURFACE = 0;
4
+ export const RootTagContext = createContext(NO_SURFACE);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@symbiote-native/solid",
3
- "version": "3.2.0",
3
+ "version": "3.4.0",
4
4
  "description": "SymbioteNative's Solid adapter — a solid-js/universal createRenderer driving real native iOS/Android views through the same engine as every other adapter.",
5
5
  "keywords": [
6
6
  "react-native",
@@ -62,19 +62,19 @@
62
62
  "dependencies": {
63
63
  "babel-preset-solid": "^1.9.12",
64
64
  "typescript": "~6.0.0",
65
- "@symbiote-native/components": "3.2.0",
66
- "@symbiote-native/css-parser": "0.5.4"
65
+ "@symbiote-native/components": "3.3.0",
66
+ "@symbiote-native/css-parser": "0.6.0"
67
67
  },
68
68
  "peerDependencies": {
69
69
  "solid-js": ">=1.9.0",
70
70
  "react-native": ">=0.86",
71
- "@symbiote-native/engine": "^1.6.0"
71
+ "@symbiote-native/engine": "^1.8.0"
72
72
  },
73
73
  "devDependencies": {
74
74
  "@babel/core": "^7.25.2",
75
75
  "solid-js": "^1.9.14",
76
- "@symbiote-native/engine": "1.6.0",
77
- "@symbiote-native/test-utils": "0.4.7"
76
+ "@symbiote-native/engine": "1.8.0",
77
+ "@symbiote-native/test-utils": "0.5.1"
78
78
  },
79
79
  "scripts": {
80
80
  "typecheck": "tsc --build",