@mittwald/react-tunnel 0.2.0-alpha.1019 → 0.2.0-alpha.1020

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,11 +1,11 @@
1
1
  "use client"
2
2
  /* */
3
- import { jsx as x } from "react/jsx-runtime";
4
- import { useId as P, useState as w, useRef as a, createContext as I, useContext as v, useLayoutEffect as g, useEffect as b } from "react";
5
- import { observable as m, makeObservable as y, action as p } from "mobx";
6
- import { observer as R } from "mobx-react-lite";
7
- const l = "default", u = "default";
8
- class c {
3
+ import { jsx as p } from "react/jsx-runtime";
4
+ import { useId as v, useState as P, useRef as a, createContext as w, useContext as E, useLayoutEffect as g, useEffect as S, useSyncExternalStore as b } from "react";
5
+ import { observable as m, makeObservable as y, action as x } from "mobx";
6
+ import { observer as T } from "mobx-react-lite";
7
+ const h = "default", C = "default";
8
+ class u {
9
9
  id;
10
10
  instanceId;
11
11
  committedChildren = m.map(
@@ -16,15 +16,15 @@ class c {
16
16
  );
17
17
  renderPhaseChildren = /* @__PURE__ */ new Map();
18
18
  nextIndex = 0;
19
- constructor(e = u, t = u) {
19
+ constructor(e = C, t = C) {
20
20
  this.id = e, this.instanceId = t, y(this, {
21
21
  id: !1,
22
- deleteChildren: p.bound,
23
- setChildren: p.bound
22
+ deleteChildren: x.bound,
23
+ setChildren: x.bound
24
24
  });
25
25
  }
26
26
  static useNew(e) {
27
- const t = P(), n = w(() => new c(e, t))[0];
27
+ const t = v(), n = P(() => new u(e, t))[0];
28
28
  return n.resetIndex(), n;
29
29
  }
30
30
  resetIndex() {
@@ -34,7 +34,7 @@ class c {
34
34
  const e = a(this.instanceId), t = a(null);
35
35
  return (t.current === null || e.current !== this.instanceId) && (e.current = this.instanceId, t.current = this.nextIndex++), t.current;
36
36
  }
37
- setChildren(e = l, t, n, r) {
37
+ setChildren(e = h, t, n, r) {
38
38
  const s = {
39
39
  id: t,
40
40
  index: n,
@@ -42,7 +42,7 @@ class c {
42
42
  }, i = this.committedChildren.get(e) ?? m.map({}, { deep: !1 });
43
43
  i.set(t, s), this.renderPhaseChildren.get(e)?.delete(t), this.committedChildren.set(e, i);
44
44
  }
45
- setRenderPhaseChildren(e = l, t, n, r) {
45
+ setRenderPhaseChildren(e = h, t, n, r) {
46
46
  const s = {
47
47
  id: t,
48
48
  index: n,
@@ -54,32 +54,35 @@ class c {
54
54
  const r = e.get(t);
55
55
  r?.delete(n), r?.size === 0 && e.delete(t);
56
56
  }
57
- deleteChildren(e = l, t) {
57
+ deleteChildren(e = h, t) {
58
58
  this.deleteChildrenFromMap(this.committedChildren, e, t), this.deleteChildrenFromMap(this.renderPhaseChildren, e, t);
59
59
  }
60
- takeRenderPhaseChildren(e) {
61
- if (this.renderPhaseChildren.has(e)) {
62
- const t = this.renderPhaseChildren.get(e)?.values();
63
- return typeof window < "u" && this.renderPhaseChildren.delete(e), t;
64
- }
65
- }
66
- getEntries(e = l) {
67
- const t = this.takeRenderPhaseChildren(e), n = this.committedChildren.get(e)?.values(), r = n ?? t;
68
- if (r) {
69
- const s = !!n, i = Array.from(r).sort(
70
- (o, h) => o.index - h.index
60
+ // Pure read — never mutate during render. `getEntries` runs inside the
61
+ // (observer) `TunnelExit` render, and React 19 may invoke a render more than
62
+ // once before committing (StrictMode double-invoke, concurrent re-render), so
63
+ // a consume-on-read here broke SSR hydration. Render-phase children are only a
64
+ // bridge for the server render and the first (pre-effect) client render; the
65
+ // exit opts into them via `useRenderPhaseFallback` while `useIsSSR()` is true.
66
+ // After hydration the committed children are authoritative — even when empty —
67
+ // so an entry that never committed (suspended, then removed) leaves no stale
68
+ // content behind.
69
+ getEntries(e = h, t = !1) {
70
+ const n = this.committedChildren.get(e)?.values(), r = t ? this.renderPhaseChildren.get(e)?.values() : void 0, s = n ?? r;
71
+ if (s) {
72
+ const i = !!n, o = Array.from(s).sort(
73
+ (l, c) => l.index - c.index
71
74
  );
72
75
  return {
73
- committed: s,
74
- entries: i
76
+ committed: i,
77
+ entries: o
75
78
  };
76
79
  }
77
80
  }
78
81
  }
79
- const C = I({
80
- state: new c()
81
- }), E = (d = u) => {
82
- let e = v(C);
82
+ const f = w({
83
+ state: new u()
84
+ }), I = (d = C) => {
85
+ let e = E(f);
83
86
  for (; e; ) {
84
87
  if (e.state.id === d)
85
88
  return e.state;
@@ -88,10 +91,10 @@ const C = I({
88
91
  throw new Error(
89
92
  `Could not get tunnel for provider ${d}. Please provider a TunnelProvider with this ID.`
90
93
  );
91
- }, N = (d) => {
92
- const { children: e, id: t } = d, n = v(C), r = c.useNew(t);
93
- return /* @__PURE__ */ x(
94
- C.Provider,
94
+ }, k = (d) => {
95
+ const { children: e, id: t } = d, n = E(f), r = u.useNew(t);
96
+ return /* @__PURE__ */ p(
97
+ f.Provider,
95
98
  {
96
99
  value: {
97
100
  state: r,
@@ -100,22 +103,26 @@ const C = I({
100
103
  children: e
101
104
  }
102
105
  );
103
- }, j = (d) => {
104
- const { children: e, id: t, staticEntryId: n, providerId: r } = d, s = E(r), i = P(), o = n ?? i, h = s.useEntryIndex(), f = a(!1);
105
- return f.current || s.setRenderPhaseChildren(t, o, h, e), g(() => {
106
- f.current = !0, s.setChildren(t, o, h, e);
107
- }, [e, t, o, h, r]), b(() => () => {
106
+ }, z = (d) => {
107
+ const { children: e, id: t, staticEntryId: n, providerId: r } = d, s = I(r), i = v(), o = n ?? i, l = s.useEntryIndex(), c = a(!1);
108
+ return c.current || s.setRenderPhaseChildren(t, o, l, e), g(() => {
109
+ c.current = !0, s.setChildren(t, o, l, e);
110
+ }, [e, t, o, l, r]), S(() => () => {
108
111
  s.deleteChildren(t, o);
109
112
  }, [t, o, r]), null;
110
- }, T = (d) => {
113
+ }, M = (d) => {
111
114
  const { children: e } = d;
112
115
  return typeof e == "function" ? e() : e;
113
- }, z = R((d) => {
114
- const { children: e, id: t, providerId: n } = d, s = E(n).getEntries(t)?.entries.map((i) => /* @__PURE__ */ x(T, { children: i.children }, i.id));
115
- return typeof e == "function" ? e(s) : s ?? e;
116
+ }, A = T((d) => {
117
+ const { children: e, id: t, providerId: n } = d, r = b(
118
+ () => () => null,
119
+ () => !1,
120
+ () => !0
121
+ ), i = I(n).getEntries(t, r)?.entries.map((o) => /* @__PURE__ */ p(M, { children: o.children }, o.id));
122
+ return typeof e == "function" ? e(i) : i ?? e;
116
123
  });
117
124
  export {
118
- j as TunnelEntry,
119
- z as TunnelExit,
120
- N as TunnelProvider
125
+ z as TunnelEntry,
126
+ A as TunnelExit,
127
+ k as TunnelProvider
121
128
  };
@@ -25,8 +25,7 @@ export declare class TunnelState {
25
25
  setRenderPhaseChildren(tunnelId: string | undefined, entryId: string, index: number, children: TunnelChildren): void;
26
26
  private deleteChildrenFromMap;
27
27
  deleteChildren(tunnelId: string | undefined, entryId: string): void;
28
- private takeRenderPhaseChildren;
29
- getEntries(tunnelId?: string): TunnelEntries | undefined;
28
+ getEntries(tunnelId?: string, useRenderPhaseFallback?: boolean): TunnelEntries | undefined;
30
29
  }
31
30
  export {};
32
31
  //# sourceMappingURL=TunnelState.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"TunnelState.d.ts","sourceRoot":"","sources":["../../src/TunnelState.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAA2B,MAAM,OAAO,CAAC;AAChE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AAI1C,eAAO,MAAM,uBAAuB,YAAY,CAAC;AAEjD,MAAM,MAAM,cAAc,GACtB,SAAS,GACT,SAAS,GACT,CAAC,CAAC,cAAc,CAAC,EAAE,SAAS,GAAG,SAAS,KAAK,SAAS,GAAG,SAAS,CAAC,CAAC;AAExE,UAAU,gBAAgB;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,cAAc,CAAC;CAC1B;AAED,UAAU,aAAa;IACrB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,gBAAgB,EAAE,CAAC;CAC7B;AAED,qBAAa,WAAW;IACtB,SAAgB,EAAE,EAAE,MAAM,CAAC;IAC3B,OAAO,CAAC,UAAU,CAAS;IAE3B,SAAgB,iBAAiB,iEAQ/B;IAEF,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAGhC;IAEJ,OAAO,CAAC,SAAS,CAAK;gBAGpB,EAAE,SAA0B,EAC5B,UAAU,SAA0B;WAWxB,MAAM,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,WAAW;IAOvC,UAAU;IAIV,aAAa;IAUb,WAAW,CAChB,QAAQ,EAAE,MAAM,YAAY,EAC5B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,cAAc,GACvB,IAAI;IAiBA,sBAAsB,CAC3B,QAAQ,EAAE,MAAM,YAAY,EAC5B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,cAAc,GACvB,IAAI;IAgBP,OAAO,CAAC,qBAAqB;IAYtB,cAAc,CAAC,QAAQ,EAAE,MAAM,YAAY,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAK1E,OAAO,CAAC,uBAAuB;IAUxB,UAAU,CAAC,QAAQ,SAAY,GAAG,aAAa,GAAG,SAAS;CAiBnE"}
1
+ {"version":3,"file":"TunnelState.d.ts","sourceRoot":"","sources":["../../src/TunnelState.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAA2B,MAAM,OAAO,CAAC;AAChE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AAI1C,eAAO,MAAM,uBAAuB,YAAY,CAAC;AAEjD,MAAM,MAAM,cAAc,GACtB,SAAS,GACT,SAAS,GACT,CAAC,CAAC,cAAc,CAAC,EAAE,SAAS,GAAG,SAAS,KAAK,SAAS,GAAG,SAAS,CAAC,CAAC;AAExE,UAAU,gBAAgB;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,cAAc,CAAC;CAC1B;AAED,UAAU,aAAa;IACrB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,gBAAgB,EAAE,CAAC;CAC7B;AAED,qBAAa,WAAW;IACtB,SAAgB,EAAE,EAAE,MAAM,CAAC;IAC3B,OAAO,CAAC,UAAU,CAAS;IAE3B,SAAgB,iBAAiB,iEAQ/B;IAEF,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAGhC;IAEJ,OAAO,CAAC,SAAS,CAAK;gBAGpB,EAAE,SAA0B,EAC5B,UAAU,SAA0B;WAWxB,MAAM,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,WAAW;IAOvC,UAAU;IAIV,aAAa;IAUb,WAAW,CAChB,QAAQ,EAAE,MAAM,YAAY,EAC5B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,cAAc,GACvB,IAAI;IAiBA,sBAAsB,CAC3B,QAAQ,EAAE,MAAM,YAAY,EAC5B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,cAAc,GACvB,IAAI;IAgBP,OAAO,CAAC,qBAAqB;IAYtB,cAAc,CAAC,QAAQ,EAAE,MAAM,YAAY,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAcnE,UAAU,CACf,QAAQ,SAAY,EACpB,sBAAsB,UAAQ,GAC7B,aAAa,GAAG,SAAS;CAmB7B"}
@@ -1 +1 @@
1
- {"version":3,"file":"TunnelExit.d.ts","sourceRoot":"","sources":["../../../src/components/TunnelExit.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAGhC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,MAAM,MAAM,kBAAkB,GAAG,cAAc,CAAC;AAEhD,MAAM,WAAW,eAAe;IAC9B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,gDAAgD;IAChD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,kBAAkB,CAAC;CAC/B;AAOD,eAAO,MAAM,UAAU,EAAE,EAAE,CAAC,eAAe,CAazC,CAAC;AAEH,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"TunnelExit.d.ts","sourceRoot":"","sources":["../../../src/components/TunnelExit.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,EAAwB,MAAM,OAAO,CAAC;AAGtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,MAAM,MAAM,kBAAkB,GAAG,cAAc,CAAC;AAEhD,MAAM,WAAW,eAAe;IAC9B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,gDAAgD;IAChD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,kBAAkB,CAAC;CAC/B;AAOD,eAAO,MAAM,UAAU,EAAE,EAAE,CAAC,eAAe,CAmBzC,CAAC;AAEH,eAAe,UAAU,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mittwald/react-tunnel",
3
- "version": "0.2.0-alpha.1019",
3
+ "version": "0.2.0-alpha.1020",
4
4
  "type": "module",
5
5
  "description": "It's like a Portal – but with React components",
6
6
  "keywords": [
@@ -37,7 +37,7 @@
37
37
  "mobx-react-lite": "^4.1.1"
38
38
  },
39
39
  "devDependencies": {
40
- "@mittwald/typescript-config": "0.2.0-alpha.1019",
40
+ "@mittwald/typescript-config": "0.2.0-alpha.1020",
41
41
  "@types/node": "^25.9.3",
42
42
  "@types/react": "^19.2",
43
43
  "@types/react-dom": "^19.2",
@@ -62,5 +62,5 @@
62
62
  "react": "^19.2.0",
63
63
  "react-dom": "^19.2.0"
64
64
  },
65
- "gitHead": "35bf2ce8d8060b2926dc35d317e7fe816ddac6a4"
65
+ "gitHead": "058d4ffed4fd5279fb7198a4b3acbd8070ff3539"
66
66
  }