nextjs-cms 0.5.62 → 0.5.63
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/core/config/loader-with-esbuild.d.ts.map +1 -1
- package/dist/core/config/loader-with-esbuild.js +1 -8
- package/dist/core/factories/section-factory-with-esbuild.d.ts +1 -2
- package/dist/core/factories/section-factory-with-esbuild.d.ts.map +1 -1
- package/dist/core/factories/section-factory-with-esbuild.js +39 -31
- package/dist/core/factories/section-factory-with-jiti.d.ts +1 -2
- package/dist/core/factories/section-factory-with-jiti.d.ts.map +1 -1
- package/dist/core/factories/section-factory-with-jiti.js +37 -23
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader-with-esbuild.d.ts","sourceRoot":"","sources":["../../../src/core/config/loader-with-esbuild.ts"],"names":[],"mappings":"AA0CA,eAAO,MAAM,sBAAsB,cAAmC,CAAA;AA0KtE;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,QAAa,OAAO,CAAC,OAAO,
|
|
1
|
+
{"version":3,"file":"loader-with-esbuild.d.ts","sourceRoot":"","sources":["../../../src/core/config/loader-with-esbuild.ts"],"names":[],"mappings":"AA0CA,eAAO,MAAM,sBAAsB,cAAmC,CAAA;AA0KtE;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,QAAa,OAAO,CAAC,OAAO,CASxD,CAAA"}
|
|
@@ -180,16 +180,9 @@ const findConfigFile = () => {
|
|
|
180
180
|
export const loadConfigModule = async () => {
|
|
181
181
|
startConfigWatcher();
|
|
182
182
|
const { found, isTs } = findConfigFile();
|
|
183
|
-
if (!isTs) {
|
|
184
|
-
// For non-TS configs, load directly
|
|
185
|
-
const url = pathToFileURL(found).href;
|
|
186
|
-
// IMPORTANT: prevent Turbopack from trying to statically analyze the specifier
|
|
187
|
-
const mod = await import(/* turbopackIgnore: true */ url);
|
|
188
|
-
return mod?.default ?? mod;
|
|
189
|
-
}
|
|
190
183
|
// For TS configs, bundle them first (like sections do)
|
|
191
184
|
const bundled = await ensureBundledConfig(found);
|
|
192
185
|
const url = `${pathToFileURL(bundled).href}?v=${configWatcherState.version}`;
|
|
193
|
-
const mod = await import(/* turbopackIgnore: true */ url);
|
|
186
|
+
const mod = await import(/* turbopackIgnore: true */ /* webpackIgnore: true */ url);
|
|
194
187
|
return mod?.default ?? mod;
|
|
195
188
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { HasItemsSection, SimpleSection, CategorySection } from '../sections/index.js';
|
|
2
2
|
import type { CategorySectionConfig, HasItemsSectionConfig, SimpleSectionConfig } from '../sections/index.js';
|
|
3
3
|
import type { SectionTypes } from '../types/index.js';
|
|
4
|
+
export declare const getSectionImportVersion: () => number;
|
|
4
5
|
type AnySectionConfig = HasItemsSectionConfig | SimpleSectionConfig | CategorySectionConfig;
|
|
5
6
|
export declare class SectionFactory {
|
|
6
7
|
/**
|
|
@@ -20,9 +21,7 @@ export declare class SectionFactory {
|
|
|
20
21
|
*/
|
|
21
22
|
private static allSectionsPromise;
|
|
22
23
|
private static allSectionsLoaded;
|
|
23
|
-
private static watcherStarted;
|
|
24
24
|
private static configVersion;
|
|
25
|
-
private static sectionWatcher;
|
|
26
25
|
private static ensureConfigFresh;
|
|
27
26
|
static bumpHotMarker(): void;
|
|
28
27
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"section-factory-with-esbuild.d.ts","sourceRoot":"","sources":["../../../src/core/factories/section-factory-with-esbuild.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACtF,OAAO,KAAK,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAC7G,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"section-factory-with-esbuild.d.ts","sourceRoot":"","sources":["../../../src/core/factories/section-factory-with-esbuild.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACtF,OAAO,KAAK,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAC7G,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AA2CrD,eAAO,MAAM,uBAAuB,cAAoC,CAAA;AAsHxE,KAAK,gBAAgB,GAAG,qBAAqB,GAAG,mBAAmB,GAAG,qBAAqB,CAAA;AAY3F,qBAAa,cAAc;IACvB;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,aAAa,WAAiD;IAE9E,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAwC;IACrE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAc;IAE5C,OAAO,CAAC,MAAM,CAAC,uBAAuB,CAA+B;IACrE,OAAO,CAAC,MAAM,CAAC,qBAAqB,CAA+B;IACnE,OAAO,CAAC,MAAM,CAAC,UAAU,CAAI;IAE7B;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAA2C;IAC5E,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAQ;IACxC,OAAO,CAAC,MAAM,CAAC,aAAa,CAAK;mBAEZ,iBAAiB;IAsBtC,MAAM,CAAC,aAAa,IAAI,IAAI;IAwB5B;;;;OAIG;WACU,WAAW,CAAC,IAAI,CAAC,EAAE,YAAY,GAAG,YAAY,EAAE,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAI3F;;;;;OAKG;WACU,mBAAmB,CAAC,EAC7B,IAAI,EACJ,KAAK,GACR,EAAE;QACC,IAAI,CAAC,EAAE,YAAY,GAAG,YAAY,EAAE,CAAA;QACpC,KAAK,EAAE;YACH,EAAE,EAAE,MAAM,CAAA;YACV,YAAY,CAAC,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,CAAA;SACjC,CAAA;KACJ,GAAG,OAAO,CAAC;QACR,MAAM,EAAE,mBAAmB,EAAE,CAAA;QAC7B,SAAS,EAAE,qBAAqB,EAAE,CAAA;QAClC,QAAQ,EAAE,qBAAqB,EAAE,CAAA;QACjC,KAAK,EAAE,MAAM,EAAE,CAAA;KAClB,CAAC;IA+BF;;;;;OAKG;WACU,UAAU,CAAC,EACpB,IAAI,EACJ,IAAI,GACP,EAAE;QACC,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,CAAC,EAAE,YAAY,GAAG,YAAY,EAAE,CAAA;KACvC,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAKpC;;;;;;OAMG;WACU,kBAAkB,CAAC,EAC5B,IAAI,EACJ,IAAI,EACJ,KAAK,GACR,EAAE;QACC,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,CAAC,EAAE,YAAY,GAAG,YAAY,EAAE,CAAA;QACpC,KAAK,EAAE;YACH,EAAE,EAAE,MAAM,CAAA;YACV,YAAY,CAAC,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,CAAA;SACjC,CAAA;KACJ,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAKpC;;;;;;;;;;OAUG;IACH,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE;QAClB,KAAK,EAAE,MAAM,eAAe,GAAG,aAAa,GAAG,eAAe,CAAA;QAC9D,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KACrB,GAAG,eAAe,GAAG,aAAa,GAAG,eAAe;IAYrD;;;;;;;;;OASG;mBACkB,GAAG;IA6FxB;;;;OAIG;mBACkB,eAAe;IAmKpC,OAAO,CAAC,MAAM,CAAC,YAAY;IAqD3B,OAAO,CAAC,MAAM,CAAC,IAAI;CAatB"}
|
|
@@ -21,6 +21,19 @@ const getCmsConfigCached = async (currentVersion = getConfigImportVersion()) =>
|
|
|
21
21
|
return cachedCmsConfig;
|
|
22
22
|
};
|
|
23
23
|
const hotMarkerFile = resolve(process.cwd(), 'components/form/helpers/_section-hot-reload.js');
|
|
24
|
+
const sectionWatcherState = (() => {
|
|
25
|
+
const key = Symbol.for('nextjs-cms.sectionWatcher');
|
|
26
|
+
const globalAny = globalThis;
|
|
27
|
+
if (!globalAny[key]) {
|
|
28
|
+
globalAny[key] = {
|
|
29
|
+
watcher: null,
|
|
30
|
+
version: 0,
|
|
31
|
+
lastEventAt: new Map(),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
return globalAny[key];
|
|
35
|
+
})();
|
|
36
|
+
export const getSectionImportVersion = () => sectionWatcherState.version;
|
|
24
37
|
// Create a require function that works in ES modules
|
|
25
38
|
const safeRequire = createRequire(import.meta.url);
|
|
26
39
|
/**
|
|
@@ -66,11 +79,6 @@ const loadEsbuildRegister = () => {
|
|
|
66
79
|
const id = 'esbuild-register/dist/node'; // avoid inline literal in require call
|
|
67
80
|
return safeRequire(id);
|
|
68
81
|
};
|
|
69
|
-
/**
|
|
70
|
-
* Runtime module import version token.
|
|
71
|
-
* Node caches ESM modules by URL. Adding `?v=` busts the cache when files change.
|
|
72
|
-
*/
|
|
73
|
-
let sectionImportVersion = 0;
|
|
74
82
|
const getEsbuild = () => safeRequire('esbuild');
|
|
75
83
|
const cacheRoot = resolve(process.cwd(), '.nextjs-cms', 'sections');
|
|
76
84
|
if (!existsSync(cacheRoot))
|
|
@@ -118,8 +126,8 @@ const loadSectionModuleRuntime = async (absPath) => {
|
|
|
118
126
|
}
|
|
119
127
|
// Dev/runtime: bundle then import the bundled output (Turbopack-safe)
|
|
120
128
|
const bundled = await ensureBundledSection(absPath);
|
|
121
|
-
const url = `${pathToFileURL(bundled).href}?v=${
|
|
122
|
-
const mod = await import(/* turbopackIgnore: true */ url);
|
|
129
|
+
const url = `${pathToFileURL(bundled).href}?v=${sectionWatcherState.version}`;
|
|
130
|
+
const mod = await import(/* turbopackIgnore: true */ /* webpackIgnore: true */ url);
|
|
123
131
|
return mod?.default;
|
|
124
132
|
};
|
|
125
133
|
/**
|
|
@@ -150,9 +158,7 @@ export class SectionFactory {
|
|
|
150
158
|
*/
|
|
151
159
|
static allSectionsPromise = null;
|
|
152
160
|
static allSectionsLoaded = false;
|
|
153
|
-
static watcherStarted = false;
|
|
154
161
|
static configVersion = -1;
|
|
155
|
-
static sectionWatcher = null;
|
|
156
162
|
static async ensureConfigFresh() {
|
|
157
163
|
const currentVersion = getConfigImportVersion();
|
|
158
164
|
const cmsConfig = await getCmsConfigCached(currentVersion);
|
|
@@ -163,13 +169,10 @@ export class SectionFactory {
|
|
|
163
169
|
this.errorCount = 0;
|
|
164
170
|
this.allSectionsPromise = null;
|
|
165
171
|
this.allSectionsLoaded = false;
|
|
166
|
-
// Reset section import version to force re-bundling
|
|
167
|
-
sectionImportVersion = 0;
|
|
168
172
|
// Close and reset the watcher if it exists
|
|
169
|
-
if (
|
|
170
|
-
await
|
|
171
|
-
|
|
172
|
-
this.watcherStarted = false;
|
|
173
|
+
if (sectionWatcherState.watcher) {
|
|
174
|
+
await sectionWatcherState.watcher.close();
|
|
175
|
+
sectionWatcherState.watcher = null;
|
|
173
176
|
}
|
|
174
177
|
}
|
|
175
178
|
return cmsConfig;
|
|
@@ -490,23 +493,17 @@ If you added an extension manually, remove it.`);
|
|
|
490
493
|
}
|
|
491
494
|
// ---------- DEV WATCHER & CACHE INVALIDATION ----------
|
|
492
495
|
static startWatcher(cmsConfig) {
|
|
493
|
-
if (!this.isDev ||
|
|
496
|
+
if (!this.isDev || sectionWatcherState.watcher)
|
|
494
497
|
return;
|
|
495
|
-
this.watcherStarted = true;
|
|
496
|
-
const watcher = chokidar.watch('**/*.section.ts', {
|
|
497
|
-
cwd: cmsConfig.sections.path,
|
|
498
|
-
ignoreInitial: true,
|
|
499
|
-
});
|
|
500
|
-
this.sectionWatcher = watcher;
|
|
501
|
-
log('Starting section watcher in dev mode...');
|
|
502
|
-
/**
|
|
503
|
-
* Invalidate section cache + bust runtime import cache.
|
|
504
|
-
* For Turbopack runtime import we increment sectionImportVersion which changes the URL (`?v=`).
|
|
505
|
-
* We still bump the hot marker to trigger Fast Refresh + react-query invalidation.
|
|
506
|
-
*/
|
|
507
498
|
const invalidateForRelPath = (relPath) => {
|
|
508
|
-
|
|
509
|
-
|
|
499
|
+
const normalized = relPath.replace(/\\/g, '/');
|
|
500
|
+
const now = Date.now();
|
|
501
|
+
const last = sectionWatcherState.lastEventAt.get(normalized);
|
|
502
|
+
if (last && now - last < 150)
|
|
503
|
+
return;
|
|
504
|
+
sectionWatcherState.lastEventAt.set(normalized, now);
|
|
505
|
+
// Increment global version to force re-bundling
|
|
506
|
+
sectionWatcherState.version++;
|
|
510
507
|
// Reset our in-process caches
|
|
511
508
|
this.sectionProcessingErrors = {};
|
|
512
509
|
this.sectionFetchingErrors = {};
|
|
@@ -516,7 +513,17 @@ If you added an extension manually, remove it.`);
|
|
|
516
513
|
log('Invalidated section cache due to change in', relPath);
|
|
517
514
|
this.bumpHotMarker();
|
|
518
515
|
};
|
|
519
|
-
watcher
|
|
516
|
+
sectionWatcherState.watcher = chokidar
|
|
517
|
+
.watch('**/*.section.ts', {
|
|
518
|
+
cwd: cmsConfig.sections.path,
|
|
519
|
+
ignoreInitial: true,
|
|
520
|
+
atomic: true,
|
|
521
|
+
awaitWriteFinish: {
|
|
522
|
+
stabilityThreshold: 100,
|
|
523
|
+
pollInterval: 20,
|
|
524
|
+
},
|
|
525
|
+
})
|
|
526
|
+
.setMaxListeners(3)
|
|
520
527
|
.on('add', (path) => {
|
|
521
528
|
log('Section file added:', path);
|
|
522
529
|
invalidateForRelPath(path);
|
|
@@ -529,6 +536,7 @@ If you added an extension manually, remove it.`);
|
|
|
529
536
|
log('Section file removed:', path);
|
|
530
537
|
invalidateForRelPath(path);
|
|
531
538
|
});
|
|
539
|
+
log('Starting section watcher in dev mode...');
|
|
532
540
|
}
|
|
533
541
|
static init() {
|
|
534
542
|
if (this.isProd) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { HasItemsSection, SimpleSection, CategorySection } from '../sections/index.js';
|
|
2
2
|
import type { CategorySectionConfig, HasItemsSectionConfig, SimpleSectionConfig } from '../sections/index.js';
|
|
3
3
|
import type { SectionTypes } from '../types/index.js';
|
|
4
|
+
export declare const getSectionImportVersion: () => number;
|
|
4
5
|
type AnySectionConfig = HasItemsSectionConfig | SimpleSectionConfig | CategorySectionConfig;
|
|
5
6
|
export declare class SectionFactory {
|
|
6
7
|
/**
|
|
@@ -20,9 +21,7 @@ export declare class SectionFactory {
|
|
|
20
21
|
*/
|
|
21
22
|
private static allSectionsPromise;
|
|
22
23
|
private static allSectionsLoaded;
|
|
23
|
-
private static watcherStarted;
|
|
24
24
|
private static configVersion;
|
|
25
|
-
private static sectionWatcher;
|
|
26
25
|
private static ensureConfigFresh;
|
|
27
26
|
static bumpHotMarker(): void;
|
|
28
27
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"section-factory-with-jiti.d.ts","sourceRoot":"","sources":["../../../src/core/factories/section-factory-with-jiti.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACtF,OAAO,KAAK,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAC7G,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AA+
|
|
1
|
+
{"version":3,"file":"section-factory-with-jiti.d.ts","sourceRoot":"","sources":["../../../src/core/factories/section-factory-with-jiti.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACtF,OAAO,KAAK,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAC7G,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AA+BrD,eAAO,MAAM,uBAAuB,cAAoC,CAAA;AAyIxE,KAAK,gBAAgB,GAAG,qBAAqB,GAAG,mBAAmB,GAAG,qBAAqB,CAAA;AAE3F,qBAAa,cAAc;IACvB;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,aAAa,WAAiD;IAE9E,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAwC;IACrE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAc;IAE5C,OAAO,CAAC,MAAM,CAAC,uBAAuB,CAA+B;IACrE,OAAO,CAAC,MAAM,CAAC,qBAAqB,CAA+B;IACnE,OAAO,CAAC,MAAM,CAAC,UAAU,CAAI;IAE7B;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAA2C;IAC5E,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAQ;IACxC,OAAO,CAAC,MAAM,CAAC,aAAa,CAAK;mBAEZ,iBAAiB;IAqBtC,MAAM,CAAC,aAAa,IAAI,IAAI;IAwB5B;;;;OAIG;WACU,WAAW,CAAC,IAAI,CAAC,EAAE,YAAY,GAAG,YAAY,EAAE,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAI3F;;;;;OAKG;WACU,mBAAmB,CAAC,EAC7B,IAAI,EACJ,KAAK,GACR,EAAE;QACC,IAAI,CAAC,EAAE,YAAY,GAAG,YAAY,EAAE,CAAA;QACpC,KAAK,EAAE;YACH,EAAE,EAAE,MAAM,CAAA;YACV,YAAY,CAAC,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,CAAA;SACjC,CAAA;KACJ,GAAG,OAAO,CAAC;QACR,MAAM,EAAE,mBAAmB,EAAE,CAAA;QAC7B,SAAS,EAAE,qBAAqB,EAAE,CAAA;QAClC,QAAQ,EAAE,qBAAqB,EAAE,CAAA;QACjC,KAAK,EAAE,MAAM,EAAE,CAAA;KAClB,CAAC;IA+BF;;;;;OAKG;WACU,UAAU,CAAC,EACpB,IAAI,EACJ,IAAI,GACP,EAAE;QACC,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,CAAC,EAAE,YAAY,GAAG,YAAY,EAAE,CAAA;KACvC,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAKpC;;;;;;OAMG;WACU,kBAAkB,CAAC,EAC5B,IAAI,EACJ,IAAI,EACJ,KAAK,GACR,EAAE;QACC,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,CAAC,EAAE,YAAY,GAAG,YAAY,EAAE,CAAA;QACpC,KAAK,EAAE;YACH,EAAE,EAAE,MAAM,CAAA;YACV,YAAY,CAAC,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,CAAA;SACjC,CAAA;KACJ,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAKpC;;;;;;;;;;OAUG;IACH,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE;QAClB,KAAK,EAAE,MAAM,eAAe,GAAG,aAAa,GAAG,eAAe,CAAA;QAC9D,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KACrB,GAAG,eAAe,GAAG,aAAa,GAAG,eAAe;IAYrD;;;;;;;;;OASG;mBACkB,GAAG;IA6FxB;;;;OAIG;mBACkB,eAAe;IAmKpC,OAAO,CAAC,MAAM,CAAC,YAAY;IAwE3B,OAAO,CAAC,MAAM,CAAC,IAAI;CAatB"}
|
|
@@ -10,6 +10,19 @@ import { db } from '../../db/client.js';
|
|
|
10
10
|
import { AdminPrivilegesTable } from '../../db/schema.js';
|
|
11
11
|
import { getCMSConfig, getConfigImportVersion } from '../config/index.js';
|
|
12
12
|
const hotMarkerFile = resolve(process.cwd(), 'components/form/helpers/_section-hot-reload.js');
|
|
13
|
+
const sectionWatcherState = (() => {
|
|
14
|
+
const key = Symbol.for('nextjs-cms.sectionWatcher');
|
|
15
|
+
const globalAny = globalThis;
|
|
16
|
+
if (!globalAny[key]) {
|
|
17
|
+
globalAny[key] = {
|
|
18
|
+
watcher: null,
|
|
19
|
+
version: 0,
|
|
20
|
+
lastEventAt: new Map(),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
return globalAny[key];
|
|
24
|
+
})();
|
|
25
|
+
export const getSectionImportVersion = () => sectionWatcherState.version;
|
|
13
26
|
// Create a require function that works in ES modules
|
|
14
27
|
const safeRequire = createRequire(import.meta.url);
|
|
15
28
|
/**
|
|
@@ -146,9 +159,7 @@ export class SectionFactory {
|
|
|
146
159
|
*/
|
|
147
160
|
static allSectionsPromise = null;
|
|
148
161
|
static allSectionsLoaded = false;
|
|
149
|
-
static watcherStarted = false;
|
|
150
162
|
static configVersion = -1;
|
|
151
|
-
static sectionWatcher = null;
|
|
152
163
|
static async ensureConfigFresh() {
|
|
153
164
|
const currentVersion = getConfigImportVersion();
|
|
154
165
|
const cmsConfig = await getCmsConfigCached(currentVersion);
|
|
@@ -159,10 +170,9 @@ export class SectionFactory {
|
|
|
159
170
|
this.errorCount = 0;
|
|
160
171
|
this.allSectionsPromise = null;
|
|
161
172
|
this.allSectionsLoaded = false;
|
|
162
|
-
if (
|
|
163
|
-
await
|
|
164
|
-
|
|
165
|
-
this.watcherStarted = false;
|
|
173
|
+
if (sectionWatcherState.watcher) {
|
|
174
|
+
await sectionWatcherState.watcher.close();
|
|
175
|
+
sectionWatcherState.watcher = null;
|
|
166
176
|
}
|
|
167
177
|
}
|
|
168
178
|
return cmsConfig;
|
|
@@ -483,24 +493,15 @@ If you added an extension manually, remove it.`);
|
|
|
483
493
|
}
|
|
484
494
|
// ---------- DEV WATCHER & CACHE INVALIDATION ----------
|
|
485
495
|
static startWatcher(cmsConfig) {
|
|
486
|
-
if (!this.isDev ||
|
|
496
|
+
if (!this.isDev || sectionWatcherState.watcher)
|
|
487
497
|
return;
|
|
488
|
-
this.watcherStarted = true;
|
|
489
|
-
const watcher = chokidar.watch('**/*.section.ts', {
|
|
490
|
-
cwd: cmsConfig.sections.path,
|
|
491
|
-
ignoreInitial: true,
|
|
492
|
-
});
|
|
493
|
-
this.sectionWatcher = watcher;
|
|
494
|
-
log('Starting section watcher in dev mode...');
|
|
495
|
-
/**
|
|
496
|
-
* Invalidate section cache + bust runtime import cache.
|
|
497
|
-
* When a section file changes, we need to:
|
|
498
|
-
* 1. Clear jiti's module cache for that file
|
|
499
|
-
* 2. Reset our in-process caches
|
|
500
|
-
* 3. Reset the promise so sections reload on next access
|
|
501
|
-
* 4. Bump the hot marker to trigger Next.js Fast Refresh
|
|
502
|
-
*/
|
|
503
498
|
const invalidateForRelPath = (relPath) => {
|
|
499
|
+
const normalized = relPath.replace(/\\/g, '/');
|
|
500
|
+
const now = Date.now();
|
|
501
|
+
const last = sectionWatcherState.lastEventAt.get(normalized);
|
|
502
|
+
if (last && now - last < 150)
|
|
503
|
+
return;
|
|
504
|
+
sectionWatcherState.lastEventAt.set(normalized, now);
|
|
504
505
|
const absPath = resolve(cmsConfig.sections.path, relPath);
|
|
505
506
|
// Clear jiti's cache for the changed file
|
|
506
507
|
clearJitiCache(absPath);
|
|
@@ -523,11 +524,23 @@ If you added an extension manually, remove it.`);
|
|
|
523
524
|
this.errorCount = 0;
|
|
524
525
|
this.allSectionsPromise = null;
|
|
525
526
|
this.allSectionsLoaded = false;
|
|
527
|
+
// Increment version to force re-bundling
|
|
528
|
+
sectionWatcherState.version++;
|
|
526
529
|
log('Invalidated section cache due to change in', relPath);
|
|
527
530
|
// Bump the hot marker to trigger Next.js Fast Refresh
|
|
528
531
|
this.bumpHotMarker();
|
|
529
532
|
};
|
|
530
|
-
watcher
|
|
533
|
+
sectionWatcherState.watcher = chokidar
|
|
534
|
+
.watch('**/*.section.ts', {
|
|
535
|
+
cwd: cmsConfig.sections.path,
|
|
536
|
+
ignoreInitial: true,
|
|
537
|
+
atomic: true,
|
|
538
|
+
awaitWriteFinish: {
|
|
539
|
+
stabilityThreshold: 100,
|
|
540
|
+
pollInterval: 20,
|
|
541
|
+
},
|
|
542
|
+
})
|
|
543
|
+
.setMaxListeners(3)
|
|
531
544
|
.on('add', (path) => {
|
|
532
545
|
log('Section file added:', path);
|
|
533
546
|
invalidateForRelPath(path);
|
|
@@ -540,6 +553,7 @@ If you added an extension manually, remove it.`);
|
|
|
540
553
|
log('Section file removed:', path);
|
|
541
554
|
invalidateForRelPath(path);
|
|
542
555
|
});
|
|
556
|
+
log('Starting section watcher in dev mode...');
|
|
543
557
|
}
|
|
544
558
|
static init() {
|
|
545
559
|
if (this.isProd) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nextjs-cms",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.63",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"type": "module",
|
|
@@ -150,8 +150,8 @@
|
|
|
150
150
|
"prettier": "^3.3.3",
|
|
151
151
|
"tsx": "^4.20.6",
|
|
152
152
|
"typescript": "^5.9.2",
|
|
153
|
-
"@lzcms/prettier-config": "0.1.0",
|
|
154
153
|
"@lzcms/eslint-config": "0.3.0",
|
|
154
|
+
"@lzcms/prettier-config": "0.1.0",
|
|
155
155
|
"@lzcms/tsconfig": "0.1.0"
|
|
156
156
|
},
|
|
157
157
|
"license": "MIT",
|