@nitronjs/framework 0.3.10 → 0.3.11

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.
@@ -1,90 +1,77 @@
1
- import React from "react";
2
- import { hydrateRoot } from "react-dom/client";
3
- // @ts-ignore — no type declarations for this package
4
- import { createFromReadableStream } from "react-server-dom-webpack/client.browser";
5
-
6
- declare global {
7
- interface Window {
8
- __NITRON_FLIGHT__?: string;
9
- __NITRON_RSC__?: {
10
- root: any;
11
- navigate: (payload: string) => void;
12
- };
13
- }
14
- }
15
-
16
- // Convert Flight payload string to a ReadableStream
17
- function payloadToStream(payload: string): ReadableStream<Uint8Array> {
18
- return new ReadableStream({
19
- start(controller) {
20
- controller.enqueue(new TextEncoder().encode(payload));
21
- controller.close();
22
- }
23
- });
24
- }
25
-
26
- // Navigate to a new page using RSC payload (called by spa.js)
27
- function navigateWithPayload(payload: string) {
28
- const rsc = window.__NITRON_RSC__;
29
-
30
- if (!rsc || !rsc.root) return;
31
-
32
- const stream = payloadToStream(payload);
33
- const response = createFromReadableStream(stream);
34
-
35
- function Root() {
36
- return React.use(response);
37
- }
38
-
39
- rsc.root.render(React.createElement(Root));
40
- }
41
-
42
- async function mount() {
43
- const payload = window.__NITRON_FLIGHT__;
44
-
45
- if (!payload) return;
46
-
47
- const stream = payloadToStream(payload);
48
- const rscResponse = createFromReadableStream(stream);
49
-
50
- // Wait for the RSC response to fully resolve before hydrating.
51
- //
52
- // Without this, hydrateRoot starts rendering AFTER the ReadableStream
53
- // has already closed. React then tries to look up component chunks
54
- // that no longer exist in the stream, causing "Connection closed" errors.
55
- //
56
- // By awaiting here, all component modules are loaded and ready BEFORE
57
- // React starts rendering. This prevents the race condition entirely.
58
- try {
59
- await rscResponse;
60
- }
61
- catch (err) {
62
- console.error('[rsc-consumer] RSC response failed to resolve:', err);
63
- return;
64
- }
65
-
66
- function Root(): React.ReactNode {
67
- return React.use(rscResponse) as React.ReactNode;
68
- }
69
-
70
- const container = document.getElementById("app");
71
-
72
- if (!container) return;
73
-
74
- const root = hydrateRoot(container, React.createElement(Root));
75
-
76
- // Expose RSC functions for SPA navigation
77
- window.__NITRON_RSC__ = {
78
- root,
79
- navigate: navigateWithPayload
80
- };
81
-
82
- delete window.__NITRON_FLIGHT__;
83
- }
84
-
85
- if (document.readyState === "loading") {
86
- document.addEventListener("DOMContentLoaded", mount);
87
- }
88
- else {
89
- mount();
90
- }
1
+ import React from "react";
2
+ import { hydrateRoot } from "react-dom/client";
3
+ // @ts-ignore — no type declarations for this package
4
+ import { createFromReadableStream } from "react-server-dom-webpack/client.browser";
5
+
6
+ declare global {
7
+ interface Window {
8
+ __NITRON_FLIGHT__?: string;
9
+ __NITRON_RSC__?: {
10
+ root: any;
11
+ navigate: (payload: string) => void;
12
+ };
13
+ }
14
+ }
15
+
16
+ function payloadToStream(payload: string): ReadableStream<Uint8Array> {
17
+ return new ReadableStream({
18
+ start(controller) {
19
+ controller.enqueue(new TextEncoder().encode(payload));
20
+ controller.close();
21
+ }
22
+ });
23
+ }
24
+
25
+ let rscResponse: any = null;
26
+
27
+ function Root(): React.ReactNode {
28
+ return React.use(rscResponse) as React.ReactNode;
29
+ }
30
+
31
+ function navigateWithPayload(payload: string) {
32
+ const rsc = window.__NITRON_RSC__;
33
+
34
+ if (!rsc || !rsc.root) return;
35
+
36
+ const stream = payloadToStream(payload);
37
+ rscResponse = createFromReadableStream(stream);
38
+
39
+ rsc.root.render(React.createElement(Root));
40
+ }
41
+
42
+ async function mount() {
43
+ const payload = window.__NITRON_FLIGHT__;
44
+
45
+ if (!payload) return;
46
+
47
+ const stream = payloadToStream(payload);
48
+ rscResponse = createFromReadableStream(stream);
49
+
50
+ try {
51
+ await rscResponse;
52
+ }
53
+ catch (err) {
54
+ console.error('[rsc-consumer] RSC response failed to resolve:', err);
55
+ return;
56
+ }
57
+
58
+ const container = document.getElementById("app");
59
+
60
+ if (!container) return;
61
+
62
+ const root = hydrateRoot(container, React.createElement(Root));
63
+
64
+ window.__NITRON_RSC__ = {
65
+ root,
66
+ navigate: navigateWithPayload
67
+ };
68
+
69
+ delete window.__NITRON_FLIGHT__;
70
+ }
71
+
72
+ if (document.readyState === "loading") {
73
+ document.addEventListener("DOMContentLoaded", mount);
74
+ }
75
+ else {
76
+ mount();
77
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nitronjs/framework",
3
- "version": "0.3.10",
3
+ "version": "0.3.11",
4
4
  "description": "NitronJS is a modern and extensible Node.js MVC framework built on Fastify. It focuses on clean architecture, modular structure, and developer productivity, offering built-in routing, middleware, configuration management, CLI tooling, and native React integration for scalable full-stack applications.",
5
5
  "bin": {
6
6
  "njs": "./cli/njs.js"