polen 0.11.0-next.26 → 0.11.0-next.28
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/build/api/builder/ssg/generate.d.ts.map +1 -1
- package/build/api/builder/ssg/generate.js +76 -50
- package/build/api/builder/ssg/generate.js.map +1 -1
- package/build/api/builder/ssg/page-generator.worker.js +59 -55
- package/build/api/builder/ssg/page-generator.worker.js.map +1 -1
- package/build/api/builder/ssg/server-runner.worker.js +34 -40
- package/build/api/builder/ssg/server-runner.worker.js.map +1 -1
- package/build/api/builder/ssg/worker-messages.d.ts +10 -0
- package/build/api/builder/ssg/worker-messages.d.ts.map +1 -1
- package/build/api/builder/ssg/worker-messages.js +7 -1
- package/build/api/builder/ssg/worker-messages.js.map +1 -1
- package/build/template/components/ReferenceLink.d.ts +1 -0
- package/build/template/components/ReferenceLink.d.ts.map +1 -1
- package/build/template/components/ReferenceLink.js.map +1 -1
- package/build/template/components/graphql/type-link.d.ts.map +1 -1
- package/build/template/components/graphql/type-link.js +7 -6
- package/build/template/components/graphql/type-link.js.map +1 -1
- package/build/vite/plugins/routes-manifest.d.ts.map +1 -1
- package/build/vite/plugins/routes-manifest.js +5 -2
- package/build/vite/plugins/routes-manifest.js.map +1 -1
- package/package.json +38 -48
- package/src/api/builder/ssg/generate.ts +111 -71
- package/src/api/builder/ssg/page-generator.worker.ts +106 -74
- package/src/api/builder/ssg/server-runner.worker.ts +39 -44
- package/src/api/builder/ssg/worker-messages.ts +11 -1
- package/src/template/components/ReferenceLink.tsx +1 -0
- package/src/template/components/graphql/type-link.tsx +21 -9
- package/src/vite/plugins/routes-manifest.ts +5 -2
- package/build/lib/extensible-data/$.d.ts +0 -2
- package/build/lib/extensible-data/$.d.ts.map +0 -1
- package/build/lib/extensible-data/$.js +0 -2
- package/build/lib/extensible-data/$.js.map +0 -1
- package/build/lib/extensible-data/extensible-data.d.ts +0 -17
- package/build/lib/extensible-data/extensible-data.d.ts.map +0 -1
- package/build/lib/extensible-data/extensible-data.js +0 -24
- package/build/lib/extensible-data/extensible-data.js.map +0 -1
- package/build/lib/vite-plugin-reactive-data/$.d.ts +0 -2
- package/build/lib/vite-plugin-reactive-data/$.d.ts.map +0 -1
- package/build/lib/vite-plugin-reactive-data/$.js +0 -2
- package/build/lib/vite-plugin-reactive-data/$.js.map +0 -1
- package/build/lib/vite-plugin-reactive-data/vite-plugin-reactive-data.d.ts +0 -32
- package/build/lib/vite-plugin-reactive-data/vite-plugin-reactive-data.d.ts.map +0 -1
- package/build/lib/vite-plugin-reactive-data/vite-plugin-reactive-data.js +0 -85
- package/build/lib/vite-plugin-reactive-data/vite-plugin-reactive-data.js.map +0 -1
- package/src/lib/extensible-data/$.ts +0 -1
- package/src/lib/extensible-data/extensible-data.ts +0 -38
- package/src/lib/vite-plugin-reactive-data/$.ts +0 -1
- package/src/lib/vite-plugin-reactive-data/vite-plugin-reactive-data.ts +0 -124
@@ -2,15 +2,11 @@
|
|
2
2
|
* Worker that generates static pages by fetching from servers.
|
3
3
|
* This is executed in a worker thread using Effect Worker API.
|
4
4
|
*/
|
5
|
-
import {
|
6
|
-
import { Path, WorkerRunner } from '@effect/platform'
|
5
|
+
import { FileSystem, Path, WorkerRunner } from '@effect/platform'
|
7
6
|
import { NodeContext, NodeRuntime, NodeWorkerRunner } from '@effect/platform-node'
|
8
|
-
import { Data, Effect, Layer } from 'effect'
|
9
|
-
import { promises as fs } from 'node:fs'
|
7
|
+
import { Array, Data, Duration, Effect, Either, Layer } from 'effect'
|
10
8
|
import { type GenerateResult, PageMessage } from './worker-messages.js'
|
11
9
|
|
12
|
-
const debug = debugPolen.sub(`api:ssg:page-generator`)
|
13
|
-
|
14
10
|
// ============================================================================
|
15
11
|
// Error Types
|
16
12
|
// ============================================================================
|
@@ -31,85 +27,118 @@ class RouteProcessingError extends Data.Error<{
|
|
31
27
|
// Generate Pages Handler
|
32
28
|
// ============================================================================
|
33
29
|
|
30
|
+
// Fetch HTML from server using Effect patterns
|
31
|
+
const fetchPage = (url: string) =>
|
32
|
+
Effect.gen(function*() {
|
33
|
+
const response = yield* Effect.tryPromise({
|
34
|
+
try: () => fetch(url),
|
35
|
+
catch: (error) => new Error(`Network error: ${error}`),
|
36
|
+
})
|
37
|
+
|
38
|
+
if (!response.ok) {
|
39
|
+
return yield* Effect.fail(
|
40
|
+
new Error(`HTTP ${response.status}: ${response.statusText}`),
|
41
|
+
)
|
42
|
+
}
|
43
|
+
|
44
|
+
return yield* Effect.tryPromise({
|
45
|
+
try: () => response.text(),
|
46
|
+
catch: (error) => new Error(`Failed to read response: ${error}`),
|
47
|
+
})
|
48
|
+
})
|
49
|
+
|
50
|
+
// Write HTML to file system
|
51
|
+
const writeHtmlFile = (outputPath: string, html: string) =>
|
52
|
+
Effect.gen(function*() {
|
53
|
+
const fs = yield* FileSystem.FileSystem
|
54
|
+
const path = yield* Path.Path
|
55
|
+
|
56
|
+
const dir = path.dirname(outputPath)
|
57
|
+
yield* fs.makeDirectory(dir, { recursive: true })
|
58
|
+
yield* fs.writeFileString(outputPath, html)
|
59
|
+
})
|
60
|
+
|
61
|
+
// Process a single route
|
62
|
+
const processRoute = (
|
63
|
+
route: string,
|
64
|
+
serverPort: number,
|
65
|
+
outputDir: string,
|
66
|
+
) =>
|
67
|
+
Effect.gen(function*() {
|
68
|
+
const path = yield* Path.Path
|
69
|
+
|
70
|
+
// Fetch the page from the server
|
71
|
+
const url = `http://localhost:${serverPort}${route}`
|
72
|
+
const html = yield* fetchPage(url).pipe(
|
73
|
+
Effect.mapError(error => new RouteProcessingError({ route, cause: error })),
|
74
|
+
)
|
75
|
+
|
76
|
+
// Determine output file path
|
77
|
+
const outputPath = path.join(
|
78
|
+
outputDir,
|
79
|
+
route === '/' ? 'index.html' : `${route.slice(1)}/index.html`,
|
80
|
+
)
|
81
|
+
|
82
|
+
// Write the HTML file
|
83
|
+
yield* writeHtmlFile(outputPath, html).pipe(
|
84
|
+
Effect.mapError(error => new RouteProcessingError({ route, cause: error })),
|
85
|
+
)
|
86
|
+
|
87
|
+
return route
|
88
|
+
})
|
89
|
+
|
34
90
|
const handlers = {
|
35
91
|
GeneratePages: (
|
36
92
|
{ routes, serverPort, outputDir }: { routes: readonly string[]; serverPort: number; outputDir: string },
|
37
93
|
) =>
|
38
94
|
Effect.gen(function*() {
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
route === '/' ? 'index.html' : `${route.slice(1)}/index.html`,
|
66
|
-
)
|
67
|
-
|
68
|
-
// Ensure directory exists
|
69
|
-
const dir = path.dirname(outputPath)
|
70
|
-
await fs.mkdir(dir, { recursive: true })
|
71
|
-
|
72
|
-
// Write the HTML file
|
73
|
-
await fs.writeFile(outputPath, html, 'utf-8')
|
74
|
-
|
75
|
-
processedCount++
|
76
|
-
|
77
|
-
// Log progress every 5 routes or on last route
|
78
|
-
if (processedCount % 5 === 0 || processedCount === routes.length) {
|
79
|
-
debug(`Progress`, {
|
80
|
-
processedCount,
|
81
|
-
totalRoutes: routes.length,
|
82
|
-
serverPort,
|
83
|
-
})
|
84
|
-
}
|
85
|
-
},
|
86
|
-
catch: (error) => {
|
87
|
-
debug(`Failed to process route`, { route, error })
|
88
|
-
return new RouteProcessingError({ route, cause: error })
|
89
|
-
},
|
90
|
-
})
|
91
|
-
}
|
95
|
+
yield* Effect.logDebug(`Starting batch generation`).pipe(
|
96
|
+
Effect.annotateLogs({
|
97
|
+
totalRoutes: routes.length,
|
98
|
+
serverPort,
|
99
|
+
}),
|
100
|
+
)
|
101
|
+
|
102
|
+
// Process all routes with timing, collecting both successes and failures
|
103
|
+
const [duration, results] = yield* Effect.forEach(
|
104
|
+
routes,
|
105
|
+
(route, index) =>
|
106
|
+
processRoute(route, serverPort, outputDir).pipe(
|
107
|
+
Effect.tap(() =>
|
108
|
+
// Log progress every 5 routes
|
109
|
+
(index + 1) % 5 === 0 || index === routes.length - 1
|
110
|
+
? Effect.logDebug(`Progress: ${index + 1}/${routes.length} routes processed`)
|
111
|
+
: Effect.void
|
112
|
+
),
|
113
|
+
Effect.either, // Convert to Either to capture both success and failure
|
114
|
+
),
|
115
|
+
{ concurrency: 1 }, // Process sequentially to avoid overwhelming the server
|
116
|
+
).pipe(Effect.timed)
|
117
|
+
|
118
|
+
// Partition results into successes and failures
|
119
|
+
const [failures, successes] = Array.partition(results, Either.isRight)
|
120
|
+
const processedCount = successes.length
|
92
121
|
|
93
122
|
const result: GenerateResult = {
|
94
|
-
success:
|
123
|
+
success: failures.length === 0,
|
95
124
|
processedCount,
|
96
|
-
duration:
|
125
|
+
duration: Duration.toMillis(duration),
|
97
126
|
memoryUsed: process.memoryUsage().heapUsed,
|
127
|
+
...(failures.length > 0 && {
|
128
|
+
error: `Failed to generate ${failures.length} out of ${routes.length} routes`,
|
129
|
+
failures: failures.map((f) => ({
|
130
|
+
route: f.left.route,
|
131
|
+
error: f.left.cause instanceof Error ? f.left.cause.message : String(f.left.cause),
|
132
|
+
})),
|
133
|
+
}),
|
98
134
|
}
|
99
135
|
|
100
|
-
|
136
|
+
yield* Effect.logDebug(`Batch generation complete`).pipe(
|
137
|
+
Effect.annotateLogs(result),
|
138
|
+
)
|
139
|
+
|
101
140
|
return result
|
102
|
-
})
|
103
|
-
Effect.catchAll((error) =>
|
104
|
-
Effect.succeed({
|
105
|
-
success: false,
|
106
|
-
processedCount: 0,
|
107
|
-
duration: Date.now() - Date.now(),
|
108
|
-
memoryUsed: process.memoryUsage().heapUsed,
|
109
|
-
error: error instanceof Error ? error.message : String(error),
|
110
|
-
})
|
111
|
-
),
|
112
|
-
),
|
141
|
+
}),
|
113
142
|
}
|
114
143
|
|
115
144
|
// ============================================================================
|
@@ -120,6 +149,9 @@ const handlers = {
|
|
120
149
|
WorkerRunner.launch(
|
121
150
|
Layer.provide(
|
122
151
|
WorkerRunner.layerSerialized(PageMessage, handlers),
|
123
|
-
Layer.
|
152
|
+
Layer.mergeAll(
|
153
|
+
NodeWorkerRunner.layer,
|
154
|
+
NodeContext.layer,
|
155
|
+
),
|
124
156
|
),
|
125
157
|
).pipe(NodeRuntime.runMain)
|
@@ -2,18 +2,15 @@
|
|
2
2
|
* Worker that runs a Polen server for SSG.
|
3
3
|
* This is executed in a child process using Effect Worker API.
|
4
4
|
*/
|
5
|
-
import { debugPolen } from '#singletons/debug'
|
6
5
|
import { WorkerRunner } from '@effect/platform'
|
7
6
|
import { NodeRuntime, NodeWorkerRunner } from '@effect/platform-node'
|
8
|
-
import { Duration, Effect, Layer, Scope } from 'effect'
|
7
|
+
import { Duration, Effect, Layer, Ref, Scope } from 'effect'
|
9
8
|
import { spawn } from 'node:child_process'
|
10
9
|
import type { ChildProcess } from 'node:child_process'
|
11
10
|
import { ServerMessage } from './worker-messages.js'
|
12
11
|
|
13
|
-
|
14
|
-
|
15
|
-
// Store the server process for cleanup
|
16
|
-
let serverProcess: ChildProcess | null = null
|
12
|
+
// Store the server process reference for cleanup
|
13
|
+
const serverProcessRef = Ref.unsafeMake<ChildProcess | null>(null)
|
17
14
|
|
18
15
|
// ============================================================================
|
19
16
|
// Handlers
|
@@ -23,20 +20,21 @@ const handlers = {
|
|
23
20
|
StartServer: ({ serverPath, port }: { serverPath: string; port: number }) =>
|
24
21
|
Effect.gen(function*() {
|
25
22
|
// If there's already a server running, stop it first
|
26
|
-
|
27
|
-
|
23
|
+
const existingProcess = yield* Ref.get(serverProcessRef)
|
24
|
+
if (existingProcess) {
|
25
|
+
existingProcess.kill('SIGTERM')
|
28
26
|
yield* Effect.sleep(Duration.millis(500))
|
29
|
-
if (!
|
30
|
-
|
27
|
+
if (!existingProcess.killed) {
|
28
|
+
existingProcess.kill('SIGKILL')
|
31
29
|
}
|
32
|
-
|
30
|
+
yield* Ref.set(serverProcessRef, null)
|
33
31
|
}
|
34
32
|
|
35
33
|
// Start the server process
|
36
|
-
|
37
|
-
debug(`Starting server with command: node ${serverPath}`)
|
34
|
+
yield* Effect.logDebug(`Starting server with command: node ${serverPath}`)
|
38
35
|
|
39
|
-
|
36
|
+
const proc = yield* Effect.sync(() => {
|
37
|
+
const serverProc = spawn('node', [serverPath], {
|
40
38
|
env: {
|
41
39
|
...process.env,
|
42
40
|
PORT: port.toString(),
|
@@ -44,18 +42,23 @@ const handlers = {
|
|
44
42
|
stdio: ['ignore', 'pipe', 'pipe'],
|
45
43
|
})
|
46
44
|
|
47
|
-
|
48
|
-
|
45
|
+
// Log server output
|
46
|
+
serverProc.stdout?.on('data', (data) => {
|
47
|
+
Effect.logDebug(`[Server ${port}] stdout: ${data.toString().trim()}`).pipe(
|
48
|
+
Effect.runSync,
|
49
|
+
)
|
49
50
|
})
|
50
51
|
|
51
|
-
|
52
|
-
|
52
|
+
serverProc.stderr?.on('data', (data) => {
|
53
|
+
Effect.logDebug(`[Server ${port}] stderr: ${data.toString().trim()}`).pipe(
|
54
|
+
Effect.runSync,
|
55
|
+
)
|
53
56
|
})
|
54
57
|
|
55
|
-
return
|
58
|
+
return serverProc
|
56
59
|
})
|
57
60
|
|
58
|
-
|
61
|
+
yield* Ref.set(serverProcessRef, proc)
|
59
62
|
|
60
63
|
// Wait for server to be ready with proper interruption support
|
61
64
|
const waitForReady = Effect.async<void>((resume) => {
|
@@ -80,7 +83,7 @@ const handlers = {
|
|
80
83
|
try {
|
81
84
|
const response = await fetch(`http://localhost:${port}/`)
|
82
85
|
if (response.ok || response.status === 404) {
|
83
|
-
|
86
|
+
Effect.logDebug(`[Server ${port}] Ready!`).pipe(Effect.runSync)
|
84
87
|
if (checkInterval) clearInterval(checkInterval)
|
85
88
|
proc.removeListener('error', errorHandler)
|
86
89
|
proc.removeListener('exit', exitHandler)
|
@@ -114,33 +117,25 @@ const handlers = {
|
|
114
117
|
Effect.die(new Error(`Server on port ${port} failed to start within 30 seconds`))),
|
115
118
|
)
|
116
119
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
debug(`Finalizer: Stopping server on port ${port}`)
|
121
|
-
if (serverProcess && !serverProcess.killed) {
|
122
|
-
serverProcess.kill('SIGTERM')
|
123
|
-
// Try to kill forcefully after a brief wait
|
124
|
-
setTimeout(() => {
|
125
|
-
if (serverProcess && !serverProcess.killed) {
|
126
|
-
serverProcess.kill('SIGKILL')
|
127
|
-
}
|
128
|
-
serverProcess = null
|
129
|
-
}, 100)
|
130
|
-
}
|
131
|
-
})
|
132
|
-
)
|
133
|
-
}).pipe(Effect.scoped),
|
134
|
-
StopServer: () =>
|
120
|
+
yield* Effect.logDebug(`Server on port ${port} started successfully`)
|
121
|
+
}),
|
122
|
+
StopServer: ({ port }: { port?: number | undefined }) =>
|
135
123
|
Effect.gen(function*() {
|
136
|
-
|
137
|
-
|
124
|
+
const serverProc = yield* Ref.get(serverProcessRef)
|
125
|
+
if (serverProc) {
|
126
|
+
if (port !== undefined) {
|
127
|
+
yield* Effect.logDebug(`Stopping server on port ${port}`)
|
128
|
+
}
|
129
|
+
serverProc.kill('SIGTERM')
|
138
130
|
// Give it time to shut down gracefully
|
139
131
|
yield* Effect.sleep(Duration.millis(500))
|
140
|
-
if (!
|
141
|
-
|
132
|
+
if (!serverProc.killed) {
|
133
|
+
serverProc.kill('SIGKILL')
|
134
|
+
}
|
135
|
+
yield* Ref.set(serverProcessRef, null)
|
136
|
+
if (port !== undefined) {
|
137
|
+
yield* Effect.logDebug(`Server on port ${port} stopped`)
|
142
138
|
}
|
143
|
-
serverProcess = null
|
144
139
|
}
|
145
140
|
}),
|
146
141
|
}
|
@@ -16,6 +16,14 @@ const GenerateResultSchema = S.Struct({
|
|
16
16
|
duration: S.Number,
|
17
17
|
memoryUsed: S.Number,
|
18
18
|
error: S.optional(S.String),
|
19
|
+
failures: S.optional(
|
20
|
+
S.Array(
|
21
|
+
S.Struct({
|
22
|
+
route: S.String,
|
23
|
+
error: S.String,
|
24
|
+
}),
|
25
|
+
),
|
26
|
+
),
|
19
27
|
})
|
20
28
|
|
21
29
|
export type GenerateResult = S.Schema.Type<typeof GenerateResultSchema>
|
@@ -40,7 +48,9 @@ export class StopServerMessage extends S.TaggedRequest<StopServerMessage>()(
|
|
40
48
|
'StopServer',
|
41
49
|
{
|
42
50
|
failure: S.Never,
|
43
|
-
payload: {
|
51
|
+
payload: {
|
52
|
+
port: S.optional(S.Number),
|
53
|
+
},
|
44
54
|
success: S.Void,
|
45
55
|
},
|
46
56
|
) {}
|
@@ -14,15 +14,27 @@ export const TypeLink: React.FC<{
|
|
14
14
|
const hasDescription = type.description && type.description.trim() !== ''
|
15
15
|
|
16
16
|
const linkContent = (
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
17
|
+
<>
|
18
|
+
<style>
|
19
|
+
{`
|
20
|
+
.type-link-content:hover code:not(:first-child) {
|
21
|
+
text-decoration: underline;
|
22
|
+
text-underline-offset: 2px;
|
23
|
+
}
|
24
|
+
`}
|
25
|
+
</style>
|
26
|
+
<ReferenceLink type={type.name} className='type-link-content'>
|
27
|
+
<Flex
|
28
|
+
align='center'
|
29
|
+
gap='1'
|
30
|
+
display='inline-flex'
|
31
|
+
>
|
32
|
+
<TypeKindIcon kind={kind} />
|
33
|
+
{` `}
|
34
|
+
<Code color={typeKindTokensIndex[kind].color} variant='ghost'>{type.name}</Code>
|
35
|
+
</Flex>
|
36
|
+
</ReferenceLink>
|
37
|
+
</>
|
26
38
|
)
|
27
39
|
|
28
40
|
// Only show HoverCard if showDescription is true AND description exists
|
@@ -3,6 +3,7 @@ import { Vite } from '#dep/vite/index'
|
|
3
3
|
import { Catalog } from '#lib/catalog/$'
|
4
4
|
import { FileRouter } from '#lib/file-router/$'
|
5
5
|
import { SchemaDefinition } from '#lib/schema-definition/$'
|
6
|
+
import { Version } from '#lib/version/$'
|
6
7
|
import { debugPolen } from '#singletons/debug'
|
7
8
|
import * as NodeFileSystem from '@effect/platform-node/NodeFileSystem'
|
8
9
|
import consola from 'consola'
|
@@ -102,12 +103,14 @@ function processVersionedCatalog(
|
|
102
103
|
): void {
|
103
104
|
for (const schema of Catalog.Versioned.getAll(catalog)) {
|
104
105
|
const version = schema.version
|
105
|
-
|
106
|
+
// Properly encode the version to its string representation
|
107
|
+
const versionValue = Version.encodeSync(version)
|
108
|
+
routes.push(`/reference/version/${versionValue}`)
|
106
109
|
|
107
110
|
processSchemaDefinition(
|
108
111
|
schema.definition,
|
109
112
|
routes,
|
110
|
-
`/reference/version/${
|
113
|
+
`/reference/version/${versionValue}`,
|
111
114
|
)
|
112
115
|
}
|
113
116
|
}
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"$.d.ts","sourceRoot":"","sources":["../../../src/lib/extensible-data/$.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,cAAc,MAAM,sBAAsB,CAAA"}
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"$.js","sourceRoot":"","sources":["../../../src/lib/extensible-data/$.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,cAAc,MAAM,sBAAsB,CAAA"}
|
@@ -1,17 +0,0 @@
|
|
1
|
-
import type { ComputedRef } from '@vue/reactivity';
|
2
|
-
type Join<$Data> = (chunks: $Data[]) => $Data;
|
3
|
-
type Create<$Data> = () => $Data;
|
4
|
-
interface DataTypeOperations<$Data> {
|
5
|
-
join: Join<$Data>;
|
6
|
-
create: Create<$Data>;
|
7
|
-
}
|
8
|
-
export declare const create: <$Data extends object = object>(dataTypeOperations: DataTypeOperations<$Data>) => ExtensibleData<$Data>;
|
9
|
-
export declare class ExtensibleData<$Data extends object = object> {
|
10
|
-
value: ComputedRef<$Data>;
|
11
|
-
private namespacedReactiveData;
|
12
|
-
private dataTypeOperations;
|
13
|
-
constructor(dataTypeOperations: DataTypeOperations<$Data>);
|
14
|
-
get(namespace: string): $Data;
|
15
|
-
}
|
16
|
-
export {};
|
17
|
-
//# sourceMappingURL=extensible-data.d.ts.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"extensible-data.d.ts","sourceRoot":"","sources":["../../../src/lib/extensible-data/extensible-data.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAmB,MAAM,iBAAiB,CAAA;AAEnE,KAAK,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,CAAA;AAC7C,KAAK,MAAM,CAAC,KAAK,IAAI,MAAM,KAAK,CAAA;AAEhC,UAAU,kBAAkB,CAAC,KAAK;IAChC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAA;IACjB,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAA;CACtB;AAED,eAAO,MAAM,MAAM,GAAI,KAAK,SAAS,MAAM,GAAG,MAAM,EAAE,oBAAoB,kBAAkB,CAAC,KAAK,CAAC,0BAElG,CAAA;AAED,qBAAa,cAAc,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM;IAChD,KAAK,EAAE,WAAW,CAAC,KAAK,CAAC,CAI9B;IAEF,OAAO,CAAC,sBAAsB,CAAqC;IAEnE,OAAO,CAAC,kBAAkB,CAA2B;gBAEzC,kBAAkB,EAAE,kBAAkB,CAAC,KAAK,CAAC;IAIzD,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,KAAK;CAO9B"}
|
@@ -1,24 +0,0 @@
|
|
1
|
-
import { computed, reactive } from '@vue/reactivity';
|
2
|
-
export const create = (dataTypeOperations) => {
|
3
|
-
return new ExtensibleData(dataTypeOperations);
|
4
|
-
};
|
5
|
-
export class ExtensibleData {
|
6
|
-
value = computed(() => {
|
7
|
-
const namespacedDataItems = Array.from(this.namespacedReactiveData.values());
|
8
|
-
const data = this.dataTypeOperations.join(namespacedDataItems);
|
9
|
-
return data;
|
10
|
-
});
|
11
|
-
namespacedReactiveData = reactive(new Map());
|
12
|
-
dataTypeOperations;
|
13
|
-
constructor(dataTypeOperations) {
|
14
|
-
this.dataTypeOperations = dataTypeOperations;
|
15
|
-
}
|
16
|
-
get(namespace) {
|
17
|
-
if (!this.namespacedReactiveData.has(namespace)) {
|
18
|
-
const data = this.dataTypeOperations.create();
|
19
|
-
this.namespacedReactiveData.set(namespace, data);
|
20
|
-
}
|
21
|
-
return this.namespacedReactiveData.get(namespace);
|
22
|
-
}
|
23
|
-
}
|
24
|
-
//# sourceMappingURL=extensible-data.js.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"extensible-data.js","sourceRoot":"","sources":["../../../src/lib/extensible-data/extensible-data.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAWpD,MAAM,CAAC,MAAM,MAAM,GAAG,CAAgC,kBAA6C,EAAE,EAAE;IACrG,OAAO,IAAI,cAAc,CAAQ,kBAAkB,CAAC,CAAA;AACtD,CAAC,CAAA;AAED,MAAM,OAAO,cAAc;IAClB,KAAK,GAAuB,QAAQ,CAAC,GAAG,EAAE;QAC/C,MAAM,mBAAmB,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,sBAAsB,CAAC,MAAM,EAAE,CAAC,CAAA;QAC5E,MAAM,IAAI,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,mBAA8B,CAAC,CAAA;QACzE,OAAO,IAAI,CAAA;IACb,CAAC,CAAC,CAAA;IAEM,sBAAsB,GAAG,QAAQ,CAAC,IAAI,GAAG,EAAiB,CAAC,CAAA;IAE3D,kBAAkB,CAA2B;IAErD,YAAY,kBAA6C;QACvD,IAAI,CAAC,kBAAkB,GAAG,kBAAkB,CAAA;IAC9C,CAAC;IAED,GAAG,CAAC,SAAiB;QACnB,IAAI,CAAC,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YAChD,MAAM,IAAI,GAAG,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE,CAAA;YAC7C,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,SAAS,EAAE,IAA8B,CAAC,CAAA;QAC5E,CAAC;QACD,OAAO,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,SAAS,CAAW,CAAA;IAC7D,CAAC;CACF"}
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"$.d.ts","sourceRoot":"","sources":["../../../src/lib/vite-plugin-reactive-data/$.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,sBAAsB,MAAM,gCAAgC,CAAA"}
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"$.js","sourceRoot":"","sources":["../../../src/lib/vite-plugin-reactive-data/$.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,sBAAsB,MAAM,gCAAgC,CAAA"}
|
@@ -1,32 +0,0 @@
|
|
1
|
-
import type { VitePluginJson } from '#lib/vite-plugin-json';
|
2
|
-
import { type ComputedRef } from '@vue/reactivity';
|
3
|
-
import type { Plugin } from 'vite';
|
4
|
-
interface ReactiveDataOptions {
|
5
|
-
/**
|
6
|
-
* Virtual module ID (e.g., 'virtual:polen/navbar') that this data will be exported from.
|
7
|
-
* The appropriate extension will be appended automatically based on moduleType.
|
8
|
-
*/
|
9
|
-
moduleId: string;
|
10
|
-
/**
|
11
|
-
* The reactive data to expose.
|
12
|
-
* Can be either:
|
13
|
-
* - A Vue computed ref (recommended)
|
14
|
-
* - A function that returns reactive data
|
15
|
-
* - A reactive value directly
|
16
|
-
*/
|
17
|
-
data: ComputedRef<object | unknown[]> | (() => object | unknown[]) | object | unknown[];
|
18
|
-
/**
|
19
|
-
* JSON codec to use
|
20
|
-
* Default: JSON
|
21
|
-
* Only used when includeJsonPlugin is true
|
22
|
-
*/
|
23
|
-
codec?: VitePluginJson.Codec;
|
24
|
-
/**
|
25
|
-
* Custom plugin name. Can use to help identify this plugin in logs if using many instances of this plugin.
|
26
|
-
@default 'reactive-data'
|
27
|
-
*/
|
28
|
-
name?: string;
|
29
|
-
}
|
30
|
-
export declare const create: (options: ReactiveDataOptions) => Plugin;
|
31
|
-
export {};
|
32
|
-
//# sourceMappingURL=vite-plugin-reactive-data.d.ts.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"vite-plugin-reactive-data.d.ts","sourceRoot":"","sources":["../../../src/lib/vite-plugin-reactive-data/vite-plugin-reactive-data.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAE3D,OAAO,EAAE,KAAK,WAAW,EAAiB,MAAM,iBAAiB,CAAA;AACjE,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,MAAM,CAAA;AAEjD,UAAU,mBAAmB;IAC3B;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAA;IAChB;;;;;;OAMG;IACH,IAAI,EAAE,WAAW,CAAC,MAAM,GAAG,OAAO,EAAE,CAAC,GAAG,CAAC,MAAM,MAAM,GAAG,OAAO,EAAE,CAAC,GAAG,MAAM,GAAG,OAAO,EAAE,CAAA;IACvF;;;;OAIG;IACH,KAAK,CAAC,EAAE,cAAc,CAAC,KAAK,CAAA;IAC5B;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAID,eAAO,MAAM,MAAM,GAAI,SAAS,mBAAmB,KAAG,MAyFrD,CAAA"}
|
@@ -1,85 +0,0 @@
|
|
1
|
-
import { debugPolen } from '#singletons/debug';
|
2
|
-
import { effect, isRef } from '@vue/reactivity';
|
3
|
-
const pluginDebug = debugPolen.sub(`vite-reactive-data`);
|
4
|
-
export const create = (options) => {
|
5
|
-
const codec = options.codec ?? JSON;
|
6
|
-
const moduleId = options.moduleId;
|
7
|
-
const name = options.name ?? `reactive-data`;
|
8
|
-
const debug = pluginDebug.sub(name);
|
9
|
-
debug(`constructor`, { moduleId });
|
10
|
-
let $server;
|
11
|
-
let $invalidationScheduled = false;
|
12
|
-
const tryInvalidate = () => {
|
13
|
-
$invalidationScheduled = false;
|
14
|
-
if (!$server)
|
15
|
-
throw new Error(`Server not available yet - this should be impossible`);
|
16
|
-
const moduleNode = $server.moduleGraph.getModuleById(moduleId);
|
17
|
-
if (moduleNode) {
|
18
|
-
debug(`invalidate`, { id: moduleNode.id });
|
19
|
-
$server.moduleGraph.invalidateModule(moduleNode);
|
20
|
-
}
|
21
|
-
else {
|
22
|
-
debug(`cannot invalidate`, {
|
23
|
-
reason: `notInModuleGraph`,
|
24
|
-
moduleId,
|
25
|
-
hint: `maybe it was not loaded yet`,
|
26
|
-
});
|
27
|
-
}
|
28
|
-
};
|
29
|
-
const scheduleInvalidate = () => {
|
30
|
-
if ($invalidationScheduled)
|
31
|
-
return; // already scheduled
|
32
|
-
$invalidationScheduled = true;
|
33
|
-
if (!$server)
|
34
|
-
return; // server will flush when ready
|
35
|
-
tryInvalidate();
|
36
|
-
};
|
37
|
-
// Helper to get the current data value
|
38
|
-
const getData = () => {
|
39
|
-
if (isRef(options.data)) {
|
40
|
-
return options.data.value;
|
41
|
-
}
|
42
|
-
else if (typeof options.data === `function`) {
|
43
|
-
return options.data();
|
44
|
-
}
|
45
|
-
else {
|
46
|
-
return options.data;
|
47
|
-
}
|
48
|
-
};
|
49
|
-
// Set up reactive effect immediately
|
50
|
-
effect(() => {
|
51
|
-
// Access data to track dependencies
|
52
|
-
const data = getData();
|
53
|
-
debug(`effect triggered`, { data });
|
54
|
-
scheduleInvalidate();
|
55
|
-
});
|
56
|
-
return {
|
57
|
-
name,
|
58
|
-
configureServer(_server) {
|
59
|
-
debug(`hook configureServer`);
|
60
|
-
$server = _server;
|
61
|
-
if ($invalidationScheduled) {
|
62
|
-
debug(`try invalidate scheduled before server was ready`);
|
63
|
-
tryInvalidate();
|
64
|
-
}
|
65
|
-
},
|
66
|
-
resolveId(id) {
|
67
|
-
if (id === moduleId) {
|
68
|
-
return moduleId;
|
69
|
-
}
|
70
|
-
},
|
71
|
-
// todo make use of Vite's builtin json plugin
|
72
|
-
// for example, call it here somehow
|
73
|
-
load(id) {
|
74
|
-
if (id !== moduleId)
|
75
|
-
return;
|
76
|
-
const data = getData();
|
77
|
-
debug(`hook load`, { data });
|
78
|
-
return {
|
79
|
-
code: codec.stringify(data),
|
80
|
-
map: null,
|
81
|
-
};
|
82
|
-
},
|
83
|
-
};
|
84
|
-
};
|
85
|
-
//# sourceMappingURL=vite-plugin-reactive-data.js.map
|