@unhead/solid-js 3.0.0-beta.1 → 3.0.0-beta.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.
- package/dist/client.d.mts +4 -3
- package/dist/client.d.ts +4 -3
- package/dist/client.mjs +5 -7
- package/dist/index.mjs +12 -10
- package/dist/server.d.mts +2 -2
- package/dist/server.d.ts +2 -2
- package/dist/server.mjs +1 -1
- package/dist/stream/client.d.mts +12 -0
- package/dist/stream/client.d.ts +12 -0
- package/dist/stream/client.mjs +9 -0
- package/dist/stream/server.d.mts +52 -0
- package/dist/stream/server.d.ts +52 -0
- package/dist/stream/server.mjs +57 -0
- package/dist/stream/vite.d.mts +27 -0
- package/dist/stream/vite.d.ts +27 -0
- package/dist/stream/vite.mjs +101 -0
- package/package.json +34 -3
package/dist/client.d.mts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ClientUnhead } from 'unhead/client';
|
|
2
|
+
export { renderDOMHead } from 'unhead/client';
|
|
3
|
+
import { CreateClientHeadOptions } from 'unhead/types';
|
|
2
4
|
export { CreateClientHeadOptions, Unhead } from 'unhead/types';
|
|
3
5
|
export { UnheadContext } from './server.mjs';
|
|
4
|
-
export { renderDOMHead } from 'unhead/client';
|
|
5
6
|
import 'solid-js';
|
|
6
7
|
import 'unhead/server';
|
|
7
8
|
|
|
8
|
-
declare function createHead(options?: CreateClientHeadOptions):
|
|
9
|
+
declare function createHead(options?: CreateClientHeadOptions): ClientUnhead;
|
|
9
10
|
|
|
10
11
|
export { createHead };
|
package/dist/client.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ClientUnhead } from 'unhead/client';
|
|
2
|
+
export { renderDOMHead } from 'unhead/client';
|
|
3
|
+
import { CreateClientHeadOptions } from 'unhead/types';
|
|
2
4
|
export { CreateClientHeadOptions, Unhead } from 'unhead/types';
|
|
3
5
|
export { UnheadContext } from './server.js';
|
|
4
|
-
export { renderDOMHead } from 'unhead/client';
|
|
5
6
|
import 'solid-js';
|
|
6
7
|
import 'unhead/server';
|
|
7
8
|
|
|
8
|
-
declare function createHead(options?: CreateClientHeadOptions):
|
|
9
|
+
declare function createHead(options?: CreateClientHeadOptions): ClientUnhead;
|
|
9
10
|
|
|
10
11
|
export { createHead };
|
package/dist/client.mjs
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
import { createHead as createHead$1
|
|
1
|
+
import { createDomRenderer, createDebouncedFn, createHead as createHead$1 } from 'unhead/client';
|
|
2
2
|
export { renderDOMHead } from 'unhead/client';
|
|
3
3
|
export { U as UnheadContext } from './shared/solid-js.BJ7JZ7E-.mjs';
|
|
4
4
|
import 'solid-js';
|
|
5
5
|
|
|
6
6
|
function createHead(options = {}) {
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
...options
|
|
12
|
-
});
|
|
7
|
+
const domRenderer = createDomRenderer();
|
|
8
|
+
let head;
|
|
9
|
+
const debouncedRenderer = createDebouncedFn(() => domRenderer(head), (fn) => setTimeout(fn, 0));
|
|
10
|
+
head = createHead$1({ render: debouncedRenderer, ...options });
|
|
13
11
|
return head;
|
|
14
12
|
}
|
|
15
13
|
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { onMount, onCleanup, useContext, createSignal, createEffect } from 'solid-js';
|
|
2
|
+
import { isServer } from 'solid-js/web';
|
|
2
3
|
import { useScript as useScript$1, useHead as useHead$1, useHeadSafe as useHeadSafe$1, useSeoMeta as useSeoMeta$1 } from 'unhead';
|
|
3
4
|
import { U as UnheadContext } from './shared/solid-js.BJ7JZ7E-.mjs';
|
|
4
5
|
|
|
@@ -20,16 +21,17 @@ function useUnhead() {
|
|
|
20
21
|
}
|
|
21
22
|
function withSideEffects(input, options, fn) {
|
|
22
23
|
const unhead = options.head || useUnhead();
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
entry
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
24
|
+
const entry = fn(unhead, input, options);
|
|
25
|
+
if (!isServer) {
|
|
26
|
+
const [entrySignal] = createSignal(entry);
|
|
27
|
+
createEffect(() => {
|
|
28
|
+
entrySignal().patch(input);
|
|
29
|
+
});
|
|
30
|
+
createEffect(() => {
|
|
31
|
+
return () => entry.dispose();
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
return entry;
|
|
33
35
|
}
|
|
34
36
|
function useHead(input = {}, options = {}) {
|
|
35
37
|
return withSideEffects(input, options, useHead$1);
|
package/dist/server.d.mts
CHANGED
|
@@ -2,8 +2,8 @@ import * as solid_js from 'solid-js';
|
|
|
2
2
|
import * as unhead_types from 'unhead/types';
|
|
3
3
|
import { Unhead } from 'unhead/types';
|
|
4
4
|
export { CreateServerHeadOptions, SSRHeadPayload, Unhead } from 'unhead/types';
|
|
5
|
-
export { createHead,
|
|
5
|
+
export { createHead, renderSSRHead, transformHtmlTemplate } from 'unhead/server';
|
|
6
6
|
|
|
7
|
-
declare const UnheadContext: solid_js.Context<Unhead<unhead_types.ResolvableHead> | null>;
|
|
7
|
+
declare const UnheadContext: solid_js.Context<Unhead<unhead_types.ResolvableHead, unknown> | null>;
|
|
8
8
|
|
|
9
9
|
export { UnheadContext };
|
package/dist/server.d.ts
CHANGED
|
@@ -2,8 +2,8 @@ import * as solid_js from 'solid-js';
|
|
|
2
2
|
import * as unhead_types from 'unhead/types';
|
|
3
3
|
import { Unhead } from 'unhead/types';
|
|
4
4
|
export { CreateServerHeadOptions, SSRHeadPayload, Unhead } from 'unhead/types';
|
|
5
|
-
export { createHead,
|
|
5
|
+
export { createHead, renderSSRHead, transformHtmlTemplate } from 'unhead/server';
|
|
6
6
|
|
|
7
|
-
declare const UnheadContext: solid_js.Context<Unhead<unhead_types.ResolvableHead> | null>;
|
|
7
|
+
declare const UnheadContext: solid_js.Context<Unhead<unhead_types.ResolvableHead, unknown> | null>;
|
|
8
8
|
|
|
9
9
|
export { UnheadContext };
|
package/dist/server.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { U as UnheadContext } from './shared/solid-js.BJ7JZ7E-.mjs';
|
|
2
|
-
export { createHead,
|
|
2
|
+
export { createHead, renderSSRHead, transformHtmlTemplate } from 'unhead/server';
|
|
3
3
|
import 'solid-js';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { UnheadContext } from '../server.mjs';
|
|
2
|
+
export { CreateStreamableClientHeadOptions, UnheadStreamQueue, createStreamableHead } from 'unhead/stream/client';
|
|
3
|
+
import 'solid-js';
|
|
4
|
+
import 'unhead/types';
|
|
5
|
+
import 'unhead/server';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Client-side HeadStream - returns null (script already executed during SSR streaming)
|
|
9
|
+
*/
|
|
10
|
+
declare function HeadStream(): null;
|
|
11
|
+
|
|
12
|
+
export { HeadStream };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { UnheadContext } from '../server.js';
|
|
2
|
+
export { CreateStreamableClientHeadOptions, UnheadStreamQueue, createStreamableHead } from 'unhead/stream/client';
|
|
3
|
+
import 'solid-js';
|
|
4
|
+
import 'unhead/types';
|
|
5
|
+
import 'unhead/server';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Client-side HeadStream - returns null (script already executed during SSR streaming)
|
|
9
|
+
*/
|
|
10
|
+
declare function HeadStream(): null;
|
|
11
|
+
|
|
12
|
+
export { HeadStream };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { ServerUnhead } from 'unhead/server';
|
|
2
|
+
import { CreateStreamableServerHeadOptions } from 'unhead/types';
|
|
3
|
+
export { UnheadContext } from '../server.mjs';
|
|
4
|
+
export { StreamingTemplateParts, WebStreamableHeadContext, prepareStreamingTemplate, renderSSRHeadShell, renderSSRHeadSuspenseChunk, wrapStream } from 'unhead/stream/server';
|
|
5
|
+
import 'solid-js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Solid-js streaming context returned by createStreamableHead.
|
|
9
|
+
*/
|
|
10
|
+
interface SolidStreamableHeadContext {
|
|
11
|
+
head: ServerUnhead;
|
|
12
|
+
/**
|
|
13
|
+
* Callback to pass to renderToStream's onCompleteShell option.
|
|
14
|
+
* This captures head entries from shell components before streaming starts.
|
|
15
|
+
*/
|
|
16
|
+
onCompleteShell: () => void;
|
|
17
|
+
/**
|
|
18
|
+
* Wrap a web ReadableStream to handle head injection automatically.
|
|
19
|
+
* Must be called after onCompleteShell has fired.
|
|
20
|
+
*/
|
|
21
|
+
wrapStream: (stream: ReadableStream<Uint8Array>, template: string) => ReadableStream<Uint8Array>;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Creates a head instance configured for Solid-js streaming SSR.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```tsx
|
|
28
|
+
* const { head, onCompleteShell, wrapStream } = createStreamableHead()
|
|
29
|
+
*
|
|
30
|
+
* const stream = renderToStream(() => (
|
|
31
|
+
* <UnheadContext.Provider value={head}>
|
|
32
|
+
* <App />
|
|
33
|
+
* </UnheadContext.Provider>
|
|
34
|
+
* ), { onCompleteShell })
|
|
35
|
+
*
|
|
36
|
+
* return wrapStream(stream, template)
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
declare function createStreamableHead(options?: CreateStreamableServerHeadOptions): SolidStreamableHeadContext;
|
|
40
|
+
/**
|
|
41
|
+
* Streaming script component - outputs inline script with current head state.
|
|
42
|
+
* The Vite plugin with streaming: true auto-injects this.
|
|
43
|
+
*
|
|
44
|
+
* Note: In SolidJS, this only outputs content AFTER the shell is complete.
|
|
45
|
+
* During shell rendering, we accumulate entries which are captured by onCompleteShell.
|
|
46
|
+
*/
|
|
47
|
+
declare function HeadStream(): {
|
|
48
|
+
t: string;
|
|
49
|
+
} | null;
|
|
50
|
+
|
|
51
|
+
export { HeadStream, createStreamableHead };
|
|
52
|
+
export type { SolidStreamableHeadContext };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { ServerUnhead } from 'unhead/server';
|
|
2
|
+
import { CreateStreamableServerHeadOptions } from 'unhead/types';
|
|
3
|
+
export { UnheadContext } from '../server.js';
|
|
4
|
+
export { StreamingTemplateParts, WebStreamableHeadContext, prepareStreamingTemplate, renderSSRHeadShell, renderSSRHeadSuspenseChunk, wrapStream } from 'unhead/stream/server';
|
|
5
|
+
import 'solid-js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Solid-js streaming context returned by createStreamableHead.
|
|
9
|
+
*/
|
|
10
|
+
interface SolidStreamableHeadContext {
|
|
11
|
+
head: ServerUnhead;
|
|
12
|
+
/**
|
|
13
|
+
* Callback to pass to renderToStream's onCompleteShell option.
|
|
14
|
+
* This captures head entries from shell components before streaming starts.
|
|
15
|
+
*/
|
|
16
|
+
onCompleteShell: () => void;
|
|
17
|
+
/**
|
|
18
|
+
* Wrap a web ReadableStream to handle head injection automatically.
|
|
19
|
+
* Must be called after onCompleteShell has fired.
|
|
20
|
+
*/
|
|
21
|
+
wrapStream: (stream: ReadableStream<Uint8Array>, template: string) => ReadableStream<Uint8Array>;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Creates a head instance configured for Solid-js streaming SSR.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```tsx
|
|
28
|
+
* const { head, onCompleteShell, wrapStream } = createStreamableHead()
|
|
29
|
+
*
|
|
30
|
+
* const stream = renderToStream(() => (
|
|
31
|
+
* <UnheadContext.Provider value={head}>
|
|
32
|
+
* <App />
|
|
33
|
+
* </UnheadContext.Provider>
|
|
34
|
+
* ), { onCompleteShell })
|
|
35
|
+
*
|
|
36
|
+
* return wrapStream(stream, template)
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
declare function createStreamableHead(options?: CreateStreamableServerHeadOptions): SolidStreamableHeadContext;
|
|
40
|
+
/**
|
|
41
|
+
* Streaming script component - outputs inline script with current head state.
|
|
42
|
+
* The Vite plugin with streaming: true auto-injects this.
|
|
43
|
+
*
|
|
44
|
+
* Note: In SolidJS, this only outputs content AFTER the shell is complete.
|
|
45
|
+
* During shell rendering, we accumulate entries which are captured by onCompleteShell.
|
|
46
|
+
*/
|
|
47
|
+
declare function HeadStream(): {
|
|
48
|
+
t: string;
|
|
49
|
+
} | null;
|
|
50
|
+
|
|
51
|
+
export { HeadStream, createStreamableHead };
|
|
52
|
+
export type { SolidStreamableHeadContext };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { useContext } from 'solid-js';
|
|
2
|
+
import { ssr } from 'solid-js/web';
|
|
3
|
+
import { createStreamableHead as createStreamableHead$1, prepareStreamingTemplate, renderSSRHeadSuspenseChunk } from 'unhead/stream/server';
|
|
4
|
+
export { prepareStreamingTemplate, renderSSRHeadShell, renderSSRHeadSuspenseChunk, wrapStream } from 'unhead/stream/server';
|
|
5
|
+
import { U as UnheadContext } from '../shared/solid-js.BJ7JZ7E-.mjs';
|
|
6
|
+
|
|
7
|
+
function createStreamableHead(options = {}) {
|
|
8
|
+
const { head } = createStreamableHead$1(options);
|
|
9
|
+
let resolveShellReady;
|
|
10
|
+
const shellReady = new Promise((resolve) => {
|
|
11
|
+
resolveShellReady = resolve;
|
|
12
|
+
});
|
|
13
|
+
head._solidShellComplete = false;
|
|
14
|
+
return {
|
|
15
|
+
head,
|
|
16
|
+
onCompleteShell: () => {
|
|
17
|
+
const shellState = head.render();
|
|
18
|
+
head.entries.clear();
|
|
19
|
+
head._solidShellComplete = true;
|
|
20
|
+
resolveShellReady(shellState);
|
|
21
|
+
},
|
|
22
|
+
wrapStream: (stream, template) => {
|
|
23
|
+
const encoder = new TextEncoder();
|
|
24
|
+
return new ReadableStream({
|
|
25
|
+
async start(controller) {
|
|
26
|
+
const shellState = await shellReady;
|
|
27
|
+
const { shell, end } = prepareStreamingTemplate(head, template, shellState);
|
|
28
|
+
controller.enqueue(encoder.encode(shell));
|
|
29
|
+
const reader = stream.getReader();
|
|
30
|
+
while (true) {
|
|
31
|
+
const { done, value } = await reader.read();
|
|
32
|
+
if (done)
|
|
33
|
+
break;
|
|
34
|
+
controller.enqueue(value);
|
|
35
|
+
}
|
|
36
|
+
reader.releaseLock();
|
|
37
|
+
controller.enqueue(encoder.encode(end));
|
|
38
|
+
controller.close();
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
const scriptTemplate = ["<script>", "<\/script>"];
|
|
45
|
+
function HeadStream() {
|
|
46
|
+
const head = useContext(UnheadContext);
|
|
47
|
+
if (!head)
|
|
48
|
+
return null;
|
|
49
|
+
if (!head._solidShellComplete)
|
|
50
|
+
return null;
|
|
51
|
+
const update = renderSSRHeadSuspenseChunk(head);
|
|
52
|
+
if (!update)
|
|
53
|
+
return null;
|
|
54
|
+
return ssr(scriptTemplate, update);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export { HeadStream, UnheadContext, createStreamableHead };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import * as vite from 'vite';
|
|
2
|
+
import { StreamingPluginOptions } from 'unhead/stream/vite';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Vite plugin for Solid.js streaming SSR support.
|
|
6
|
+
* Automatically injects HeadStream components into Solid components that use useHead hooks.
|
|
7
|
+
*
|
|
8
|
+
* @returns Vite plugin configuration object with:
|
|
9
|
+
* - `name`: Plugin identifier
|
|
10
|
+
* - `enforce`: Plugin execution order ('pre')
|
|
11
|
+
* - `transform`: Transform hook for processing JSX/TSX files
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* // vite.config.ts
|
|
16
|
+
* import { unheadSolidPlugin } from '@unhead/solid-js/stream/vite'
|
|
17
|
+
*
|
|
18
|
+
* export default {
|
|
19
|
+
* plugins: [
|
|
20
|
+
* unheadSolidPlugin()
|
|
21
|
+
* ]
|
|
22
|
+
* }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
declare function unheadSolidPlugin(options?: Pick<StreamingPluginOptions, 'mode'>): vite.Plugin<any>;
|
|
26
|
+
|
|
27
|
+
export { unheadSolidPlugin as default, unheadSolidPlugin };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import * as vite from 'vite';
|
|
2
|
+
import { StreamingPluginOptions } from 'unhead/stream/vite';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Vite plugin for Solid.js streaming SSR support.
|
|
6
|
+
* Automatically injects HeadStream components into Solid components that use useHead hooks.
|
|
7
|
+
*
|
|
8
|
+
* @returns Vite plugin configuration object with:
|
|
9
|
+
* - `name`: Plugin identifier
|
|
10
|
+
* - `enforce`: Plugin execution order ('pre')
|
|
11
|
+
* - `transform`: Transform hook for processing JSX/TSX files
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* // vite.config.ts
|
|
16
|
+
* import { unheadSolidPlugin } from '@unhead/solid-js/stream/vite'
|
|
17
|
+
*
|
|
18
|
+
* export default {
|
|
19
|
+
* plugins: [
|
|
20
|
+
* unheadSolidPlugin()
|
|
21
|
+
* ]
|
|
22
|
+
* }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
declare function unheadSolidPlugin(options?: Pick<StreamingPluginOptions, 'mode'>): vite.Plugin<any>;
|
|
26
|
+
|
|
27
|
+
export { unheadSolidPlugin as default, unheadSolidPlugin };
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import MagicString from 'magic-string';
|
|
2
|
+
import { parseAndWalk } from 'oxc-walker';
|
|
3
|
+
import { createStreamingPlugin } from 'unhead/stream/vite';
|
|
4
|
+
|
|
5
|
+
function transform(code, id, isSSR, s) {
|
|
6
|
+
const lang = id.endsWith(".tsx") ? "tsx" : id.endsWith(".jsx") ? "jsx" : "tsx";
|
|
7
|
+
const returns = [];
|
|
8
|
+
let currentFnHasHead = false;
|
|
9
|
+
const fnStack = [];
|
|
10
|
+
const importPath = isSSR ? "@unhead/solid-js/stream/server" : "@unhead/solid-js/stream/client";
|
|
11
|
+
let existingImport = null;
|
|
12
|
+
let lastImportEnd = -1;
|
|
13
|
+
const result = parseAndWalk(code, id, {
|
|
14
|
+
parseOptions: { lang },
|
|
15
|
+
enter(node) {
|
|
16
|
+
if (node.type === "ImportDeclaration") {
|
|
17
|
+
if (node.source.value === importPath) {
|
|
18
|
+
existingImport = {
|
|
19
|
+
start: node.start,
|
|
20
|
+
end: node.end,
|
|
21
|
+
specifiers: node.specifiers?.map((spec) => spec.local?.name).filter(Boolean) || []
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
if (node.end > lastImportEnd)
|
|
25
|
+
lastImportEnd = node.end;
|
|
26
|
+
this.skip();
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const isFn = node.type === "FunctionDeclaration" || node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression";
|
|
30
|
+
if (isFn) {
|
|
31
|
+
fnStack.push(currentFnHasHead);
|
|
32
|
+
if (!node.body) {
|
|
33
|
+
currentFnHasHead = false;
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const bodyCode = code.slice(node.body.start, node.body.end);
|
|
37
|
+
currentFnHasHead = bodyCode.includes("useHead") || bodyCode.includes("useSeoMeta") || bodyCode.includes("useHeadSafe");
|
|
38
|
+
if (currentFnHasHead && (node.body.type === "JSXElement" || node.body.type === "JSXFragment")) {
|
|
39
|
+
returns.push({ jsxStart: node.body.start, jsxEnd: node.body.end });
|
|
40
|
+
}
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (currentFnHasHead && node.type === "ReturnStatement") {
|
|
44
|
+
if (!node.argument)
|
|
45
|
+
return;
|
|
46
|
+
let arg = node.argument;
|
|
47
|
+
if (arg.type === "ParenthesizedExpression" && arg.expression)
|
|
48
|
+
arg = arg.expression;
|
|
49
|
+
if (arg.type === "JSXElement" || arg.type === "JSXFragment")
|
|
50
|
+
returns.push({ jsxStart: arg.start, jsxEnd: arg.end });
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
leave(node) {
|
|
54
|
+
const isFn = node.type === "FunctionDeclaration" || node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression";
|
|
55
|
+
if (isFn) {
|
|
56
|
+
currentFnHasHead = fnStack.pop();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
if (result.errors.length > 0)
|
|
61
|
+
return false;
|
|
62
|
+
if (returns.length === 0)
|
|
63
|
+
return false;
|
|
64
|
+
returns.sort((a, b) => b.jsxStart - a.jsxStart);
|
|
65
|
+
for (const ret of returns) {
|
|
66
|
+
const jsxCode = code.slice(ret.jsxStart, ret.jsxEnd);
|
|
67
|
+
s.overwrite(ret.jsxStart, ret.jsxEnd, `<><HeadStream />${jsxCode}</>`);
|
|
68
|
+
}
|
|
69
|
+
const foundImport = existingImport;
|
|
70
|
+
if (foundImport) {
|
|
71
|
+
if (!foundImport.specifiers.includes("HeadStream")) {
|
|
72
|
+
const inner = foundImport.specifiers.join(", ");
|
|
73
|
+
s.overwrite(foundImport.start, foundImport.end, `import { ${inner ? `${inner}, ` : ""}HeadStream } from '${importPath}'`);
|
|
74
|
+
}
|
|
75
|
+
} else if (lastImportEnd > -1) {
|
|
76
|
+
s.appendLeft(lastImportEnd, `
|
|
77
|
+
import { HeadStream } from '${importPath}'`);
|
|
78
|
+
} else {
|
|
79
|
+
s.prepend(`import { HeadStream } from '${importPath}'
|
|
80
|
+
`);
|
|
81
|
+
}
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
function unheadSolidPlugin(options) {
|
|
85
|
+
return createStreamingPlugin({
|
|
86
|
+
framework: "@unhead/solid-js",
|
|
87
|
+
filter: /\.[jt]sx$/,
|
|
88
|
+
mode: options?.mode,
|
|
89
|
+
transform(code, id, opts) {
|
|
90
|
+
const s = new MagicString(code);
|
|
91
|
+
if (!transform(code, id, opts?.ssr ?? false, s))
|
|
92
|
+
return null;
|
|
93
|
+
return {
|
|
94
|
+
code: s.toString(),
|
|
95
|
+
map: s.generateMap({ includeContent: true, source: id })
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export { unheadSolidPlugin as default, unheadSolidPlugin };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unhead/solid-js",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "3.0.0-beta.
|
|
4
|
+
"version": "3.0.0-beta.11",
|
|
5
5
|
"description": "Full-stack <head> manager built for SolidJS.",
|
|
6
6
|
"author": "Harlan Wilton <harlan@harlanzw.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -29,6 +29,14 @@
|
|
|
29
29
|
"types": "./dist/client.d.ts",
|
|
30
30
|
"default": "./dist/client.mjs"
|
|
31
31
|
},
|
|
32
|
+
"./stream/server": {
|
|
33
|
+
"types": "./dist/stream/server.d.ts",
|
|
34
|
+
"default": "./dist/stream/server.mjs"
|
|
35
|
+
},
|
|
36
|
+
"./stream/client": {
|
|
37
|
+
"types": "./dist/stream/client.d.ts",
|
|
38
|
+
"default": "./dist/stream/client.mjs"
|
|
39
|
+
},
|
|
32
40
|
"./utils": {
|
|
33
41
|
"types": "./dist/utils.d.ts",
|
|
34
42
|
"default": "./dist/utils.mjs"
|
|
@@ -36,6 +44,10 @@
|
|
|
36
44
|
"./plugins": {
|
|
37
45
|
"types": "./dist/plugins.d.ts",
|
|
38
46
|
"default": "./dist/plugins.mjs"
|
|
47
|
+
},
|
|
48
|
+
"./stream/vite": {
|
|
49
|
+
"types": "./dist/stream/vite.d.ts",
|
|
50
|
+
"default": "./dist/stream/vite.mjs"
|
|
39
51
|
}
|
|
40
52
|
},
|
|
41
53
|
"main": "dist/index.mjs",
|
|
@@ -49,11 +61,20 @@
|
|
|
49
61
|
"client": [
|
|
50
62
|
"dist/client"
|
|
51
63
|
],
|
|
64
|
+
"stream/server": [
|
|
65
|
+
"dist/stream/server"
|
|
66
|
+
],
|
|
67
|
+
"stream/client": [
|
|
68
|
+
"dist/stream/client"
|
|
69
|
+
],
|
|
52
70
|
"plugins": [
|
|
53
71
|
"dist/plugins"
|
|
54
72
|
],
|
|
55
73
|
"utils": [
|
|
56
74
|
"dist/utils"
|
|
75
|
+
],
|
|
76
|
+
"stream/vite": [
|
|
77
|
+
"dist/stream/vite"
|
|
57
78
|
]
|
|
58
79
|
}
|
|
59
80
|
},
|
|
@@ -62,7 +83,13 @@
|
|
|
62
83
|
"dist"
|
|
63
84
|
],
|
|
64
85
|
"peerDependencies": {
|
|
65
|
-
"solid-js": ">=
|
|
86
|
+
"solid-js": ">=1.9.0",
|
|
87
|
+
"vite": ">=6"
|
|
88
|
+
},
|
|
89
|
+
"peerDependenciesMeta": {
|
|
90
|
+
"vite": {
|
|
91
|
+
"optional": true
|
|
92
|
+
}
|
|
66
93
|
},
|
|
67
94
|
"build": {
|
|
68
95
|
"external": [
|
|
@@ -70,13 +97,17 @@
|
|
|
70
97
|
]
|
|
71
98
|
},
|
|
72
99
|
"dependencies": {
|
|
73
|
-
"
|
|
100
|
+
"magic-string": "^0.30.21",
|
|
101
|
+
"oxc-parser": "^0.106.0",
|
|
102
|
+
"oxc-walker": "^0.7.0",
|
|
103
|
+
"unhead": "3.0.0-beta.11"
|
|
74
104
|
},
|
|
75
105
|
"devDependencies": {
|
|
76
106
|
"@solidjs/testing-library": "^0.8.10",
|
|
77
107
|
"@testing-library/jest-dom": "^6.9.1",
|
|
78
108
|
"@testing-library/user-event": "14.6.1",
|
|
79
109
|
"solid-js": "^1.9.10",
|
|
110
|
+
"vite": "^7.3.1",
|
|
80
111
|
"vite-plugin-solid": "^2.11.10"
|
|
81
112
|
},
|
|
82
113
|
"scripts": {
|