forgepress 0.0.1 → 0.0.2

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 (56) hide show
  1. package/dist/THIRD-PARTY-LICENSES.md +28 -83
  2. package/dist/_chunks/client.d.mts +1 -1
  3. package/dist/_chunks/config.mjs +61 -19
  4. package/dist/_chunks/{validate.mjs → content.mjs} +350 -217
  5. package/dist/_chunks/fetch.mjs +2 -2
  6. package/dist/_chunks/files.mjs +32 -0
  7. package/dist/_chunks/libs/diff.mjs +485 -0
  8. package/dist/_chunks/media.mjs +282 -0
  9. package/dist/_chunks/once.mjs +16 -0
  10. package/dist/_chunks/output.mjs +98 -252
  11. package/dist/_chunks/plugin.mjs +87 -0
  12. package/dist/_chunks/preview.mjs +248 -0
  13. package/dist/_chunks/project.d.mts +7 -0
  14. package/dist/_chunks/reader.mjs +5 -9
  15. package/dist/_chunks/reader2.mjs +150 -202
  16. package/dist/_chunks/references.mjs +8 -5
  17. package/dist/_chunks/resolve.d.mts +2 -0
  18. package/dist/_chunks/response.mjs +5 -0
  19. package/dist/_chunks/routes.mjs +9 -0
  20. package/dist/_chunks/serialize.mjs +82 -0
  21. package/dist/_chunks/settings.mjs +328 -0
  22. package/dist/_chunks/settings2.mjs +2 -0
  23. package/dist/_chunks/types.d.mts +229 -24
  24. package/dist/_chunks/types2.d.mts +25 -0
  25. package/dist/_chunks/value.mjs +123 -1
  26. package/dist/cli/bin.mjs +50 -37
  27. package/dist/editor/index.mjs +9961 -8653
  28. package/dist/index.d.mts +2 -3
  29. package/dist/index.mjs +14 -24
  30. package/dist/next/preview.d.mts +1 -0
  31. package/dist/next/preview.mjs +3 -0
  32. package/dist/next/reload.d.mts +1 -0
  33. package/dist/next/reload.mjs +20 -0
  34. package/dist/next/settings.d.mts +12 -0
  35. package/dist/next/settings.mjs +2 -0
  36. package/dist/plugin/next.d.mts +11 -0
  37. package/dist/plugin/next.mjs +213 -0
  38. package/dist/plugin/nuxt.d.mts +7 -0
  39. package/dist/plugin/nuxt.mjs +52 -0
  40. package/dist/plugin/watcher.d.mts +1 -0
  41. package/dist/plugin/watcher.mjs +23 -0
  42. package/dist/preview/index.d.mts +1 -2
  43. package/dist/preview/index.mjs +1 -243
  44. package/dist/preview/react.d.mts +1 -0
  45. package/dist/preview/react.mjs +34 -0
  46. package/dist/unplugin.d.mts +12 -17
  47. package/dist/unplugin.mjs +1 -500
  48. package/package.json +72 -8
  49. package/dist/_chunks/config.d.mts +0 -35
  50. package/dist/_chunks/entry.d.mts +0 -194
  51. package/dist/_chunks/libs/@oxc-project/types.d.mts +0 -1297
  52. package/dist/_chunks/libs/@rolldown/pluginutils.d.mts +0 -62
  53. package/dist/_chunks/libs/rolldown.d.mts +0 -4711
  54. package/dist/_chunks/output2.mjs +0 -333
  55. package/dist/_chunks/parse.mjs +0 -22
  56. package/dist/_chunks/types.mjs +0 -2
package/dist/index.d.mts CHANGED
@@ -1,6 +1,5 @@
1
- import { Entry, EntryMeta, EntryRef, EntryStatus, ForgePressEntry, ForgePressOutput, ForgePressSchema, ForgePressSchemaRegistry, OutputMeta, OutputOf, RegisteredSchema, SchemaLocale } from "./_chunks/entry.mjs";
2
- import { OutputCollection, OutputEntry, OutputIndex, OutputManifest } from "./_chunks/types.mjs";
3
- import { ForgePressConfig, OutputConfig } from "./_chunks/config.mjs";
1
+ import { Entry, EntryMeta, EntryRef, EntryStatus, ForgePressConfig, ForgePressEntry, ForgePressOutput, ForgePressSchema, ForgePressSchemaRegistry, OutputConfig, OutputMeta, OutputOf, RegisteredSchema, SchemaLocale } from "./_chunks/types.mjs";
2
+ import { OutputCollection, OutputEntry, OutputIndex, OutputManifest } from "./_chunks/types2.mjs";
4
3
  export declare function defineForgePressConfig(config: ForgePressConfig): ForgePressConfig;
5
4
  type Operator = 'eq' | 'ne' | 'gt' | 'gte' | 'lt' | 'lte' | 'in' | 'contains';
6
5
  type CollectionName<TSchema extends ForgePressSchema> = keyof TSchema['collections'] & string;
package/dist/index.mjs CHANGED
@@ -1,6 +1,7 @@
1
- import { isRecord, quote } from "./_chunks/value.mjs";
2
- import { entryKey } from "./_chunks/references.mjs";
3
- import { OUTPUT_INDEX } from "./_chunks/types.mjs";
1
+ import { OUTPUT_META_KEYS, pick, quote } from "./_chunks/value.mjs";
2
+ import { entryKey, isEntryRef } from "./_chunks/references.mjs";
3
+ import { OUTPUT_INDEX } from "./_chunks/response.mjs";
4
+ import { keyed } from "./_chunks/once.mjs";
4
5
  import { fetchReader } from "./_chunks/fetch.mjs";
5
6
  import { overlaid } from "./_chunks/overlay.mjs";
6
7
  import { reader } from "#content-reader";
@@ -8,7 +9,7 @@ function defineForgePressConfig(config) {
8
9
  return config;
9
10
  }
10
11
  function comparable(value) {
11
- return isRecord(value) && typeof value.collection === "string" && typeof value.id === "string" ? value.id : value;
12
+ return isEntryRef(value) ? value.id : value;
12
13
  }
13
14
  function compare(left, right) {
14
15
  const first = comparable(left);
@@ -47,13 +48,8 @@ function evaluate(entries, plan) {
47
48
  if (plan.limit !== void 0) result = result.slice(0, plan.limit);
48
49
  return result;
49
50
  }
50
- const META = [
51
- "id",
52
- "createdAt",
53
- "updatedAt"
54
- ];
55
51
  function refsOf(value) {
56
- return (Array.isArray(value) ? value : [value]).filter((item) => isRecord(item) && typeof item.collection === "string" && typeof item.id === "string");
52
+ return (Array.isArray(value) ? value : [value]).filter(isEntryRef);
57
53
  }
58
54
  function listing(names) {
59
55
  return names.map(quote).join(", ");
@@ -125,7 +121,7 @@ var Builder = class {
125
121
  const manifest = await snapshot.manifest(collection, locale);
126
122
  const unlinked = plan.with.filter((field) => manifest.links[field] === void 0);
127
123
  if (unlinked.length > 0) throw new Error(`[forgepress] .with() loads relation and dynamic fields, and ${listing(unlinked)} ${unlinked.length === 1 ? "is not one" : "are not"} in ${quote(collection)}`);
128
- const listed = /* @__PURE__ */ new Set([...META, ...manifest.indexed]);
124
+ const listed = /* @__PURE__ */ new Set([...OUTPUT_META_KEYS, ...manifest.indexed]);
129
125
  const unindexed = [...new Set([...plan.where, ...plan.sort].map((clause) => clause.field))].filter((field) => !listed.has(field));
130
126
  if (unindexed.length > 0 && index.dev) console.warn(`[forgepress] query(${quote(collection)}) filters or sorts by ${listing(unindexed)}, which ${unindexed.length === 1 ? "is" : "are"} not indexed, so every entry is loaded. Add index: true to ${unindexed.length === 1 ? "the field" : "the fields"} in the schema`);
131
127
  const selected = evaluate(unindexed.length > 0 ? await snapshot.entries(collection, locale, manifest.entries.map((entry) => entry.id)) : manifest.entries, limit === void 0 ? plan : {
@@ -135,8 +131,8 @@ var Builder = class {
135
131
  const listedOnly = plan.pick !== void 0 && [...plan.pick, ...plan.with].every((field) => listed.has(field));
136
132
  const rows = unindexed.length > 0 || listedOnly ? selected : await snapshot.entries(collection, locale, selected.map((entry) => entry.id));
137
133
  const linked = plan.with.length > 0 ? await this.link(snapshot, manifest, rows) : rows;
138
- const { pick } = plan;
139
- const picked = pick === void 0 ? linked : linked.map((row) => Object.fromEntries(pick.filter((field) => row[field] !== void 0).map((field) => [field, row[field]])));
134
+ const fields = plan.pick;
135
+ const picked = fields === void 0 ? linked : linked.map((row) => pick(row, fields));
140
136
  return structuredClone(picked);
141
137
  }
142
138
  async link(snapshot, manifest, rows) {
@@ -197,18 +193,12 @@ function manifestPath(index, collection, locale) {
197
193
  return path;
198
194
  }
199
195
  function createLoader(read) {
200
- const files = /* @__PURE__ */ new Map();
196
+ const files = keyed();
201
197
  function file(path) {
202
- let pending = files.get(path);
203
- if (!pending) {
204
- pending = read(path).then((value) => {
205
- if (value === void 0) throw new MissingFile(path);
206
- return value;
207
- });
208
- pending.catch(() => files.delete(path));
209
- files.set(path, pending);
210
- }
211
- return pending;
198
+ return files(path, () => read(path).then((value) => {
199
+ if (value === void 0) throw new MissingFile(path);
200
+ return value;
201
+ }));
212
202
  }
213
203
  async function snapshot() {
214
204
  const index = await read(OUTPUT_INDEX);
@@ -0,0 +1 @@
1
+ export {}
@@ -0,0 +1,3 @@
1
+ import { enablePreview } from "../_chunks/preview.mjs";
2
+ enablePreview();
3
+ export {};
@@ -0,0 +1 @@
1
+ export {}
@@ -0,0 +1,20 @@
1
+ import { EVENTS } from "../_chunks/routes.mjs";
2
+ import { settings_default } from "../_chunks/settings2.mjs";
3
+ const RETRY = 1e3;
4
+ const LONGEST_RETRY = 3e4;
5
+ function connect(delay) {
6
+ const socket = new WebSocket(`${settings_default.devServer.replace(/^http/, "ws")}${EVENTS}`);
7
+ let opened = false;
8
+ socket.addEventListener("open", () => {
9
+ opened = true;
10
+ });
11
+ socket.addEventListener("message", (event) => {
12
+ if (event.data === "reload") location.reload();
13
+ });
14
+ socket.addEventListener("close", () => {
15
+ const next = opened ? RETRY : Math.min(delay * 2, LONGEST_RETRY);
16
+ setTimeout(connect, next, next);
17
+ });
18
+ }
19
+ connect(RETRY);
20
+ export {};
@@ -0,0 +1,12 @@
1
+ import { ContentConfig, ProviderConfig, ResolvedMedia } from "../_chunks/types.mjs";
2
+ import "../_chunks/resolve.mjs";
3
+ interface EditorSettings {
4
+ local: boolean;
5
+ devServer: string;
6
+ provider?: ProviderConfig | undefined;
7
+ format?: ContentConfig | undefined;
8
+ contentPath: string;
9
+ media: ResolvedMedia;
10
+ }
11
+ declare const _default: EditorSettings;
12
+ export { _default as default };
@@ -0,0 +1,2 @@
1
+ import { settings_default } from "../_chunks/settings2.mjs";
2
+ export { settings_default as default };
@@ -0,0 +1,11 @@
1
+ import { Options } from "../_chunks/project.mjs";
2
+ import { NextConfig } from "next";
3
+ export interface NextOptions extends Options {
4
+ preview?: boolean;
5
+ }
6
+ export type NextConfigFunction = (phase: string, context: {
7
+ defaultConfig: NextConfig;
8
+ }) => NextConfig | Promise<NextConfig>;
9
+ export declare function withForgePress(nextConfig: NextConfig | NextConfigFunction, options?: NextOptions): (phase: string, context: {
10
+ defaultConfig: NextConfig;
11
+ }) => Promise<NextConfig>;
@@ -0,0 +1,213 @@
1
+ import { isRecord } from "../_chunks/value.mjs";
2
+ import { keyed } from "../_chunks/once.mjs";
3
+ import { errorMessage } from "../_chunks/error.mjs";
4
+ import { buildOutput } from "../_chunks/output.mjs";
5
+ import { toPosix } from "../_chunks/files.mjs";
6
+ import { EVENTS } from "../_chunks/routes.mjs";
7
+ import { SETTINGS_ID, createDevContent, editorSettings, loadProject, syncTypes } from "../_chunks/settings.mjs";
8
+ import { basename, dirname, extname, join, relative, resolve, sep } from "node:path";
9
+ import process from "node:process";
10
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
11
+ import { fileURLToPath } from "node:url";
12
+ import { createServer } from "node:http";
13
+ import { Worker, isMainThread } from "node:worker_threads";
14
+ import { applyEdits, modify, parse } from "jsonc-parser";
15
+ import { WebSocketServer } from "ws";
16
+ const DEVELOPMENT = "phase-development-server";
17
+ const BUILD = "phase-production-build";
18
+ const SETTINGS_MODULE = "forgepress/next/settings";
19
+ const SETTINGS_VARIABLE = "__FORGEPRESS_SETTINGS__";
20
+ const PREVIEW_MODULE = "forgepress/next/preview";
21
+ const RELOAD_MODULE = "forgepress/next/reload";
22
+ const VUE_FLAGS = {
23
+ __VUE_OPTIONS_API__: true,
24
+ __VUE_PROD_DEVTOOLS__: false,
25
+ __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: false
26
+ };
27
+ const SERVERS = Symbol.for("forgepress:next:servers");
28
+ const LOCAL_ORIGIN = /^https?:\/\/(?:(?:[^/:]+\.)?localhost|127\.0\.0\.1|\[::1\])(?::\d+)?$/;
29
+ const PREFLIGHT = {
30
+ "access-control-allow-methods": "GET, POST, DELETE",
31
+ "access-control-allow-headers": "content-type",
32
+ "access-control-max-age": "600"
33
+ };
34
+ const INDENT = /^[ \t]+(?=\S)/m;
35
+ const DIST = `${dirname(dirname(fileURLToPath(import.meta.url)))}${sep}`;
36
+ const WATCHER = new URL(`./watcher${extname(fileURLToPath(import.meta.url))}`, import.meta.url);
37
+ function dynamicConfigImport(warning) {
38
+ return Boolean(warning.module?.resource?.startsWith(DIST) && warning.message?.includes("the request of a dependency is an expression"));
39
+ }
40
+ const logger = {
41
+ info: (message) => process.stdout.write(`${message}\n`),
42
+ warn: (message) => console.warn(message),
43
+ error: (message) => console.error(message)
44
+ };
45
+ function localPage(request) {
46
+ const { origin } = request.headers;
47
+ const site = request.headers["sec-fetch-site"];
48
+ if (origin !== void 0) return LOCAL_ORIGIN.test(origin);
49
+ return site === void 0 || site === "none" || site === "same-origin";
50
+ }
51
+ const LOCAL_PAGES = {
52
+ accepts: localPage,
53
+ refusal: "the dev endpoint only accepts requests from pages opened on localhost"
54
+ };
55
+ function end(response, status, text) {
56
+ response.statusCode = status;
57
+ response.end(text);
58
+ }
59
+ function servers() {
60
+ const scope = globalThis;
61
+ scope[SERVERS] ??= keyed();
62
+ return scope[SERVERS];
63
+ }
64
+ function formatting(text) {
65
+ const indent = INDENT.exec(text)?.[0] ?? " ";
66
+ return {
67
+ insertSpaces: !indent.startsWith(" "),
68
+ tabSize: indent.length,
69
+ eol: text.includes("\r\n") ? "\r\n" : "\n"
70
+ };
71
+ }
72
+ function includeContent(root, config, tsconfig) {
73
+ const file = resolve(root, tsconfig);
74
+ if (!existsSync(file)) return;
75
+ const folder = toPosix(relative(dirname(file), join(root, config.paths.dir)));
76
+ const pattern = `${folder}/**/*.ts`;
77
+ if (!folder.split("/").some((segment) => segment.startsWith("."))) return;
78
+ const text = readFileSync(file, "utf8");
79
+ const errors = [];
80
+ const parsed = parse(text, errors, { allowTrailingComma: true });
81
+ if (errors.length > 0 || !isRecord(parsed) || !Array.isArray(parsed.include)) {
82
+ logger.warn(`[forgepress] add ${JSON.stringify(pattern)} to "include" in ${basename(file)}, so TypeScript knows the schema`);
83
+ return;
84
+ }
85
+ if (parsed.include.includes(pattern)) return;
86
+ writeFileSync(file, applyEdits(text, modify(text, ["include", parsed.include.length], pattern, {
87
+ isArrayInsertion: true,
88
+ formattingOptions: formatting(text)
89
+ })));
90
+ logger.info(`[forgepress] added ${JSON.stringify(pattern)} to "include" in ${basename(file)}, so TypeScript knows the schema`);
91
+ }
92
+ function watchContent(dir, schema, changed) {
93
+ const watcher = new Worker(WATCHER, { workerData: {
94
+ dir,
95
+ schema
96
+ } });
97
+ let watching = false;
98
+ return new Promise((ready, fail) => {
99
+ watcher.on("message", (file) => {
100
+ if (file !== null) return changed(file);
101
+ watching = true;
102
+ watcher.unref();
103
+ ready();
104
+ });
105
+ watcher.on("error", (error) => {
106
+ if (watching) logger.error(`[forgepress] stopped watching the content folder: ${errorMessage(error)}`);
107
+ else fail(error);
108
+ });
109
+ });
110
+ }
111
+ function listen(server) {
112
+ return new Promise((done, fail) => {
113
+ server.once("error", fail);
114
+ server.listen(0, "127.0.0.1", () => done(`127.0.0.1:${server.address().port}`));
115
+ });
116
+ }
117
+ async function startDevServer(root, config, write) {
118
+ const pages = new WebSocketServer({ noServer: true });
119
+ const dev = createDevContent(root, config, logger, () => {
120
+ for (const page of pages.clients) page.send("reload");
121
+ }, LOCAL_PAGES);
122
+ await watchContent(join(root, config.paths.dir), join(root, config.paths.schema), dev.changed);
123
+ await dev.refresh();
124
+ const server = createServer();
125
+ const host = await listen(server);
126
+ server.on("request", (request, response) => {
127
+ const { origin } = request.headers;
128
+ if (request.headers.host !== host) return end(response, 403);
129
+ if (origin !== void 0) {
130
+ response.setHeader("access-control-allow-origin", origin);
131
+ response.setHeader("vary", "origin");
132
+ }
133
+ if (request.method === "OPTIONS") {
134
+ if (!LOCAL_PAGES.accepts(request)) return end(response, 403, LOCAL_PAGES.refusal);
135
+ for (const [name, value] of Object.entries(PREFLIGHT)) response.setHeader(name, value);
136
+ return end(response, 204);
137
+ }
138
+ if (!write) return end(response, 404);
139
+ dev.endpoint(request, response, () => end(response, 404));
140
+ });
141
+ server.on("upgrade", (request, socket, head) => {
142
+ if (request.headers.host !== host || request.url !== EVENTS || !LOCAL_PAGES.accepts(request)) {
143
+ socket.destroy();
144
+ return;
145
+ }
146
+ socket.unref();
147
+ pages.handleUpgrade(request, socket, head, (page) => page.on("error", () => page.terminate()));
148
+ });
149
+ server.unref();
150
+ return `http://${host}`;
151
+ }
152
+ function devServer(root, config, write) {
153
+ return servers()(root, () => startDevServer(root, config, write));
154
+ }
155
+ async function prepare(phase, next, options) {
156
+ const project = await loadProject(process.cwd(), options);
157
+ const { root, config } = project;
158
+ const serving = phase === DEVELOPMENT && isMainThread;
159
+ if (isMainThread && (phase === DEVELOPMENT || phase === BUILD)) {
160
+ syncTypes(root, config);
161
+ includeContent(root, config, next.typescript?.tsconfigPath ?? "tsconfig.json");
162
+ }
163
+ return {
164
+ ...project,
165
+ local: phase === DEVELOPMENT && options.write !== false,
166
+ server: serving ? await devServer(root, config, options.write !== false) : void 0
167
+ };
168
+ }
169
+ function extend(next, project, options) {
170
+ const extended = {
171
+ compiler: {
172
+ ...next.compiler,
173
+ define: {
174
+ ...VUE_FLAGS,
175
+ ...next.compiler?.define,
176
+ [SETTINGS_VARIABLE]: JSON.stringify(editorSettings(project.local, project.config, project.server))
177
+ },
178
+ runAfterProductionCompile: async (metadata) => {
179
+ await buildOutput(project.root, project.config);
180
+ await next.compiler?.runAfterProductionCompile?.(metadata);
181
+ }
182
+ },
183
+ turbopack: {
184
+ ...next.turbopack,
185
+ resolveAlias: {
186
+ ...next.turbopack?.resolveAlias,
187
+ [SETTINGS_ID]: SETTINGS_MODULE
188
+ }
189
+ },
190
+ webpack: (config, context) => {
191
+ const result = next.webpack ? next.webpack(config, context) : config;
192
+ result.plugins = [...result.plugins ?? [], new context.webpack.NormalModuleReplacementPlugin(/^virtual:forgepress\/settings$/, SETTINGS_MODULE)];
193
+ result.ignoreWarnings = [...result.ignoreWarnings ?? [], dynamicConfigImport];
194
+ return result;
195
+ },
196
+ instrumentationClientInject: [
197
+ ...next.instrumentationClientInject ?? [],
198
+ ...options.preview === false ? [] : [PREVIEW_MODULE],
199
+ ...project.server ? [RELOAD_MODULE] : []
200
+ ]
201
+ };
202
+ return {
203
+ ...next,
204
+ ...extended
205
+ };
206
+ }
207
+ function withForgePress(nextConfig, options = {}) {
208
+ return async (phase, context) => {
209
+ const found = typeof nextConfig === "function" ? await nextConfig(phase, context) : nextConfig;
210
+ return extend(found, await prepare(phase, found, options), options);
211
+ };
212
+ }
213
+ export { withForgePress };
@@ -0,0 +1,7 @@
1
+ import { Options } from "../_chunks/project.mjs";
2
+ import { NuxtModule } from "@nuxt/schema";
3
+ export interface ModuleOptions extends Options {
4
+ preview?: boolean;
5
+ }
6
+ declare const forgepress: NuxtModule<ModuleOptions>;
7
+ export { forgepress as default };
@@ -0,0 +1,52 @@
1
+ import { toPosix } from "../_chunks/files.mjs";
2
+ import { loadProject } from "../_chunks/settings.mjs";
3
+ import { configFile } from "../_chunks/config.mjs";
4
+ import { vitePlugin } from "../_chunks/plugin.mjs";
5
+ import { join, relative } from "node:path";
6
+ import { addPluginTemplate, addVitePlugin, defineNuxtModule } from "@nuxt/kit";
7
+ const PREVIEW_PLUGIN = `import { defineNuxtPlugin, refreshNuxtData, usePreviewMode } from '#app'
8
+ import { enablePreview, onPreviewChange, previewing } from 'forgepress/preview'
9
+
10
+ export default defineNuxtPlugin({
11
+ name: 'forgepress:preview',
12
+ setup(nuxtApp) {
13
+ enablePreview()
14
+
15
+ const { enabled } = usePreviewMode({ shouldEnable: previewing })
16
+
17
+ onPreviewChange(() => nuxtApp.runWithContext(() => {
18
+ enabled.value = previewing()
19
+
20
+ return refreshNuxtData()
21
+ }))
22
+ },
23
+ })
24
+ `;
25
+ const forgepress = defineNuxtModule({
26
+ meta: {
27
+ name: "forgepress",
28
+ configKey: "forgepress"
29
+ },
30
+ async setup(options, nuxt) {
31
+ const { root, config } = await loadProject(nuxt.options.rootDir, options);
32
+ addVitePlugin(vitePlugin({
33
+ ...options,
34
+ root
35
+ }));
36
+ nuxt.hook("prepare:types", ({ tsConfig, nodeTsConfig }) => {
37
+ tsConfig.include ??= [];
38
+ tsConfig.include.push(toPosix(relative(nuxt.options.buildDir, join(root, config.paths.dir, "**/*.ts"))));
39
+ const file = configFile(root);
40
+ if (file) {
41
+ nodeTsConfig.include ??= [];
42
+ nodeTsConfig.include.push(toPosix(relative(nuxt.options.buildDir, join(root, file))));
43
+ }
44
+ });
45
+ if (options.preview !== false) addPluginTemplate({
46
+ filename: "forgepress/preview.client.mjs",
47
+ getContents: () => PREVIEW_PLUGIN,
48
+ mode: "client"
49
+ });
50
+ }
51
+ });
52
+ export { forgepress as default };
@@ -0,0 +1 @@
1
+ export {}
@@ -0,0 +1,23 @@
1
+ import { basename, dirname, join } from "node:path";
2
+ import { existsSync, watch } from "node:fs";
3
+ import { parentPort, workerData } from "node:worker_threads";
4
+ const { dir, schema } = workerData;
5
+ function changed(file) {
6
+ parentPort?.postMessage(file);
7
+ }
8
+ function start() {
9
+ if (!existsSync(dir)) return false;
10
+ watch(dir, { recursive: true }, (_, name) => {
11
+ if (name) changed(join(dir, name));
12
+ });
13
+ return true;
14
+ }
15
+ if (!start() && existsSync(dirname(dir))) {
16
+ const parent = watch(dirname(dir), (_, name) => {
17
+ if (name !== basename(dir) || !start()) return;
18
+ parent.close();
19
+ changed(schema);
20
+ });
21
+ }
22
+ parentPort?.postMessage(null);
23
+ export {};
@@ -1,5 +1,4 @@
1
- import "../_chunks/entry.mjs";
2
- import "../_chunks/config.mjs";
1
+ import "../_chunks/types.mjs";
3
2
  export declare function previewing(): boolean;
4
3
  export declare function onPreviewChange(listener: () => void): () => void;
5
4
  export declare function enablePreview(): boolean;