@acdh-oeaw/content-lib 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.
- package/dist/index.js +27 -21
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import * as crypto from "node:crypto";
|
|
2
2
|
import * as fs from "node:fs/promises";
|
|
3
|
+
import { availableParallelism } from "node:os";
|
|
3
4
|
import * as path from "node:path";
|
|
4
5
|
import { debuglog } from "node:util";
|
|
5
6
|
import { addTrailingSlash, log } from "@acdh-oeaw/lib";
|
|
6
7
|
import * as watcher from "@parcel/watcher";
|
|
8
|
+
import plimit from "p-limit";
|
|
7
9
|
|
|
8
10
|
//#region src/index.ts
|
|
9
11
|
const debug = debuglog("content-lib");
|
|
@@ -74,7 +76,7 @@ function serialize(value) {
|
|
|
74
76
|
const filePath = `./${hash}.js`;
|
|
75
77
|
debug(`Adding javascript import for "${filePath}".`);
|
|
76
78
|
const identifier = addImport(filePath);
|
|
77
|
-
addFiles(filePath, value$1.content);
|
|
79
|
+
addFiles(filePath, `// @ts-nocheck\n${value$1.content}`);
|
|
78
80
|
return identifier;
|
|
79
81
|
}
|
|
80
82
|
if (value$1 instanceof JsonImport) {
|
|
@@ -97,6 +99,9 @@ function serialize(value) {
|
|
|
97
99
|
}
|
|
98
100
|
async function createContentProcessor(config) {
|
|
99
101
|
debug("Creating content processor...\n");
|
|
102
|
+
const concurrency = availableParallelism();
|
|
103
|
+
const limit = plimit(concurrency);
|
|
104
|
+
debug(`Concurrency: ${String(concurrency)}.\n`);
|
|
100
105
|
const outputDirectoryBasePath = path.join(process.cwd(), ".content", "generated");
|
|
101
106
|
debug("Clearing output directory...\n");
|
|
102
107
|
await fs.rm(outputDirectoryBasePath, {
|
|
@@ -111,7 +116,7 @@ async function createContentProcessor(config) {
|
|
|
111
116
|
};
|
|
112
117
|
for (const collection of config.collections) {
|
|
113
118
|
const absoluteDirectoryPath = addTrailingSlash(path.resolve(collection.directory));
|
|
114
|
-
const outputDirectoryPath = path.join(outputDirectoryBasePath, collection.name);
|
|
119
|
+
const outputDirectoryPath = path.join(outputDirectoryBasePath, collection.name.toLowerCase().replaceAll(/[^a-z0-9_-]/g, "-"));
|
|
115
120
|
await fs.mkdir(outputDirectoryPath, { recursive: true });
|
|
116
121
|
collections.push({
|
|
117
122
|
...collection,
|
|
@@ -124,43 +129,44 @@ async function createContentProcessor(config) {
|
|
|
124
129
|
debug("Generating...\n");
|
|
125
130
|
for (const collection of collections) {
|
|
126
131
|
debug(`Reading collection "${collection.name}"...`);
|
|
127
|
-
|
|
132
|
+
await limit.map(Array.from(collection.data), async ([id, { item }]) => {
|
|
128
133
|
if (signal?.aborted === true) {
|
|
129
|
-
debug("Aborted
|
|
134
|
+
debug("Aborted reading collections.");
|
|
135
|
+
limit.clearQueue();
|
|
130
136
|
return;
|
|
131
137
|
}
|
|
132
138
|
const content = await collection.read(item);
|
|
133
139
|
collection.data.get(id).content = content;
|
|
134
|
-
debug(`- Read item "${id}"
|
|
135
|
-
}
|
|
140
|
+
debug(`- Read item "${id}".`);
|
|
141
|
+
});
|
|
136
142
|
debug(`Done reading ${String(collection.data.size)} item(s) in collection "${collection.name}".\n`);
|
|
137
143
|
}
|
|
138
144
|
for (const collection of collections) {
|
|
139
145
|
debug(`Transforming collection "${collection.name}"...`);
|
|
140
|
-
|
|
146
|
+
await limit.map(Array.from(collection.data), async ([id, { content, item }]) => {
|
|
141
147
|
if (signal?.aborted === true) {
|
|
142
|
-
debug("Aborted transforming collections
|
|
148
|
+
debug("Aborted transforming collections.");
|
|
149
|
+
limit.clearQueue();
|
|
143
150
|
return;
|
|
144
151
|
}
|
|
145
152
|
const document = await collection.transform(content, item, context);
|
|
146
153
|
collection.data.get(id).document = document;
|
|
147
|
-
debug(`- Transformed item "${id}"
|
|
148
|
-
}
|
|
154
|
+
debug(`- Transformed item "${id}".`);
|
|
155
|
+
});
|
|
149
156
|
debug(`Done transforming ${String(collection.data.size)} item(s) in collection "${collection.name}".\n`);
|
|
150
157
|
}
|
|
151
158
|
if (signal?.aborted === true) {
|
|
152
|
-
debug("Aborted writing collections
|
|
159
|
+
debug("Aborted writing collections.");
|
|
153
160
|
return;
|
|
154
161
|
}
|
|
155
162
|
for (const collection of collections) {
|
|
156
|
-
debug(`Writing collection "${collection.name}"
|
|
157
|
-
const outputFilePath = path.join(collection.outputDirectoryPath, "index.js");
|
|
163
|
+
debug(`Writing collection "${collection.name}".`);
|
|
158
164
|
const [serialized, files] = serialize(collection.data);
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
const outputFilePath
|
|
162
|
-
await fs.writeFile(outputFilePath
|
|
163
|
-
}
|
|
165
|
+
files.set("index.js", serialized);
|
|
166
|
+
await limit.map(Array.from(files), async ([filePath, fileContent]) => {
|
|
167
|
+
const outputFilePath = path.join(collection.outputDirectoryPath, filePath);
|
|
168
|
+
await fs.writeFile(outputFilePath, fileContent, { encoding: "utf-8" });
|
|
169
|
+
});
|
|
164
170
|
}
|
|
165
171
|
}
|
|
166
172
|
async function build() {
|
|
@@ -190,7 +196,7 @@ async function createContentProcessor(config) {
|
|
|
190
196
|
content: null,
|
|
191
197
|
document: null
|
|
192
198
|
});
|
|
193
|
-
debug(`- Added item "${id}" (path: "${filePath}")
|
|
199
|
+
debug(`- Added item "${id}" (path: "${filePath}").`);
|
|
194
200
|
}
|
|
195
201
|
debug(`Done adding ${String(collection.data.size)} item(s) to collection "${collection.name}".\n`);
|
|
196
202
|
}
|
|
@@ -228,7 +234,7 @@ async function createContentProcessor(config) {
|
|
|
228
234
|
log.error(error);
|
|
229
235
|
return;
|
|
230
236
|
}
|
|
231
|
-
debug(`- ${String(events.length)} events in collection "${collection.name}"
|
|
237
|
+
debug(`- ${String(events.length)} events in collection "${collection.name}".`);
|
|
232
238
|
for (const event of events) {
|
|
233
239
|
const relativeFilePath = event.path.slice(collection.absoluteDirectoryPath.length);
|
|
234
240
|
if (collection.include.some((pattern) => {
|
|
@@ -287,7 +293,7 @@ async function createContentProcessor(config) {
|
|
|
287
293
|
subscriptions.add(subscription);
|
|
288
294
|
}
|
|
289
295
|
async function unsubscribe() {
|
|
290
|
-
debug("Cleaning up
|
|
296
|
+
debug("Cleaning up...");
|
|
291
297
|
if (timer != null) clearTimeout(timer);
|
|
292
298
|
timer = null;
|
|
293
299
|
if (controller != null) controller.abort();
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["value: string","filePath: string","config: CollectionConfig<TCollectionItemContent, TCollectionDocument>","config: T","path: string","path","content: string","value: Map<string, any>","imports: Array<string>","type: \"js\" | \"json\"","value","config: ContentConfig","collections: Array<Collection>","context: TransformContext","signal?: AbortSignal","outputFilePath","error: unknown","item: CollectionItem","timer: ReturnType<typeof setTimeout> | null","controller: AbortController | null","events","error"],"sources":["../src/index.ts"],"sourcesContent":["import * as crypto from \"node:crypto\";\nimport * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport { debuglog } from \"node:util\";\n\nimport { addTrailingSlash, log } from \"@acdh-oeaw/lib\";\nimport * as watcher from \"@parcel/watcher\";\n\n//\n\nconst debug = debuglog(\"content-lib\");\n\n//\n\nfunction createContentHash(value: string): string {\n\treturn crypto.createHash(\"sha256\").update(value).digest(\"hex\");\n}\n\nfunction createIdFromFilePath(filePath: string): string {\n\tconst parsed = path.parse(filePath);\n\n\tif (parsed.name.toLowerCase() === \"index\") {\n\t\treturn path.basename(parsed.dir);\n\t}\n\n\treturn parsed.name;\n}\n\n//\n\ntype MaybePromise<T> = T | Promise<T>;\n\ntype NonEmptyReadonlyArray<T> = readonly [T, ...Array<T>];\n\ntype GlobString = string;\n\ninterface CollectionItem {\n\t/** Unique identifier. */\n\tid: string;\n\t/** File path relative to colleciton directory. */\n\tfilePath: string;\n\t/** File path relative to current working directory. */\n\tabsoluteFilePath: string;\n\t/** File modification timestamp. */\n\ttimestamp: number;\n}\n\ninterface TransformContext {\n\tcreateImportDeclaration: (path: string) => ImportDeclaration;\n\tcreateJavaScriptImport: (content: string) => JavaScriptImport;\n\tcreateJsonImport: (content: string) => JsonImport;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport interface CollectionConfig<TCollectionItemContent = any, TCollectionDocument = any> {\n\tname: string;\n\tdirectory: string;\n\tinclude: NonEmptyReadonlyArray<GlobString>;\n\texclude?: ReadonlyArray<GlobString>;\n\tread: (item: CollectionItem) => MaybePromise<TCollectionItemContent>;\n\ttransform: (\n\t\tcontent: TCollectionItemContent,\n\t\titem: CollectionItem,\n\t\tcontext: TransformContext,\n\t) => MaybePromise<TCollectionDocument>;\n}\n\nexport function createCollection<TCollectionItemContent, TCollectionDocument>(\n\tconfig: CollectionConfig<TCollectionItemContent, TCollectionDocument>,\n): CollectionConfig<TCollectionItemContent, TCollectionDocument> {\n\treturn config;\n}\n\nexport interface ContentConfig {\n\tcollections: Array<CollectionConfig>;\n}\n\nexport function createConfig<T extends ContentConfig>(config: T): T {\n\treturn config;\n}\n\n//\n\n// function createItemCacheKey(item: CollectionItem): string {\n// \treturn String(item.timestamp);\n// }\n\n//\n\nclass ImportDeclaration {\n\tpath: string;\n\n\tconstructor(path: string) {\n\t\tthis.path = path;\n\t}\n}\n\nfunction createImportDeclaration(path: string): ImportDeclaration {\n\treturn new ImportDeclaration(path);\n}\n\nclass JavaScriptImport {\n\tcontent: string;\n\n\tconstructor(content: string) {\n\t\tthis.content = content;\n\t}\n}\n\nfunction createJavaScriptImport(content: string): JavaScriptImport {\n\treturn new JavaScriptImport(content);\n}\n\nclass JsonImport {\n\tcontent: string;\n\n\tconstructor(content: string) {\n\t\tthis.content = content;\n\t}\n}\n\nfunction createJsonImport(content: string): JsonImport {\n\treturn new JsonImport(content);\n}\n\n//\n\nconst prefix = \"__i__\";\nconst re = new RegExp(`\"(${prefix}\\\\d+)\"`, \"g\");\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction serialize(value: Map<string, any>): [string, Map<string, string>] {\n\tdebug(\"Serializing...\\n\");\n\n\tconst imports: Array<string> = [];\n\n\tfunction addImport(filePath: string, type: \"js\" | \"json\" = \"js\"): string {\n\t\tconst identifier = [prefix, imports.length].join(\"\");\n\t\timports.push(\n\t\t\t`import ${identifier} from \"${filePath}\"${type !== \"js\" ? ` with { type: \"${type}\" }` : \"\"};`,\n\t\t);\n\n\t\treturn identifier;\n\t}\n\n\tconst files = new Map<string, string>();\n\n\tfunction addFiles(filePath: string, content: string): void {\n\t\tfiles.set(filePath, content);\n\t}\n\n\tconst json = JSON.stringify(\n\t\tArray.from(value),\n\t\t// TODO: Should we support (multiple) named imports?\n\t\t(_key, value) => {\n\t\t\tif (value instanceof ImportDeclaration) {\n\t\t\t\tconst filePath = value.path;\n\n\t\t\t\tdebug(`Adding import declaration for \"${filePath}\".`);\n\t\t\t\tconst identifier = addImport(filePath);\n\n\t\t\t\treturn identifier;\n\t\t\t}\n\n\t\t\tif (value instanceof JavaScriptImport) {\n\t\t\t\tconst hash = createContentHash(value.content);\n\t\t\t\tconst filePath = `./${hash}.js`;\n\n\t\t\t\tdebug(`Adding javascript import for \"${filePath}\".`);\n\t\t\t\tconst identifier = addImport(filePath);\n\t\t\t\taddFiles(filePath, value.content);\n\n\t\t\t\treturn identifier;\n\t\t\t}\n\n\t\t\tif (value instanceof JsonImport) {\n\t\t\t\tconst hash = createContentHash(value.content);\n\t\t\t\tconst filePath = `./${hash}.json`;\n\n\t\t\t\tdebug(`Adding json import for \"${filePath}\".`);\n\t\t\t\tconst identifier = addImport(filePath, \"json\");\n\t\t\t\taddFiles(filePath, value.content);\n\n\t\t\t\treturn identifier;\n\t\t\t}\n\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return\n\t\t\treturn value;\n\t\t},\n\t\t2,\n\t)\n\t\t/** Remove quotes from import identifiers. */\n\t\t.replaceAll(re, \"$1\");\n\n\tlet result = \"\";\n\n\tif (imports.length > 0) {\n\t\tresult += imports.join(\"\\n\");\n\t\tresult += \"\\n\\n\";\n\t}\n\n\tresult += `const items = new Map(${json});\\n\\nexport default items;`;\n\n\treturn [result, files];\n}\n\n//\n\ninterface Collection extends CollectionConfig {\n\tabsoluteDirectoryPath: string;\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tdata: Map<CollectionItem[\"id\"], { item: CollectionItem; content: any; document: any }>; // TODO: revisit\n\toutputDirectoryPath: string;\n}\n\ninterface BuildStats {\n\tcollections: number;\n\tdocuments: number;\n}\n\nexport interface ContentProcessor {\n\tbuild: () => Promise<BuildStats>;\n\twatch: () => Promise<Set<watcher.AsyncSubscription>>;\n}\n\nexport async function createContentProcessor(config: ContentConfig): Promise<ContentProcessor> {\n\tdebug(\"Creating content processor...\\n\");\n\n\tconst outputDirectoryBasePath = path.join(process.cwd(), \".content\", \"generated\");\n\n\tdebug(\"Clearing output directory...\\n\");\n\tawait fs.rm(outputDirectoryBasePath, { force: true, recursive: true });\n\n\tconst collections: Array<Collection> = [];\n\n\tconst context: TransformContext = {\n\t\tcreateImportDeclaration,\n\t\tcreateJavaScriptImport,\n\t\tcreateJsonImport,\n\t};\n\n\tfor (const collection of config.collections) {\n\t\tconst absoluteDirectoryPath = addTrailingSlash(path.resolve(collection.directory));\n\n\t\tconst outputDirectoryPath = path.join(outputDirectoryBasePath, collection.name);\n\t\tawait fs.mkdir(outputDirectoryPath, { recursive: true });\n\n\t\tcollections.push({\n\t\t\t...collection,\n\t\t\tabsoluteDirectoryPath,\n\t\t\tdata: new Map(),\n\t\t\toutputDirectoryPath,\n\t\t});\n\t}\n\n\tasync function generate(signal?: AbortSignal): Promise<void> {\n\t\tdebug(\"Generating...\\n\");\n\n\t\tfor (const collection of collections) {\n\t\t\tdebug(`Reading collection \"${collection.name}\"...`);\n\n\t\t\tfor (const [id, { item }] of collection.data) {\n\t\t\t\tif (signal?.aborted === true) {\n\t\t\t\t\tdebug(\"Aborted reeading collections...\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// FIXME: race condition: what if file has been deleted in the meantime\n\t\t\t\t// TODO: skip item when `read()` returns `null`?\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n\t\t\t\tconst content = await collection.read(item);\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n\t\t\t\tcollection.data.get(id)!.content = content;\n\n\t\t\t\tdebug(`- Read item \"${id}\"...`);\n\t\t\t}\n\n\t\t\tdebug(\n\t\t\t\t`Done reading ${String(collection.data.size)} item(s) in collection \"${collection.name}\".\\n`,\n\t\t\t);\n\t\t}\n\n\t\tfor (const collection of collections) {\n\t\t\tdebug(`Transforming collection \"${collection.name}\"...`);\n\n\t\t\tfor (const [id, { content, item }] of collection.data) {\n\t\t\t\tif (signal?.aborted === true) {\n\t\t\t\t\tdebug(\"Aborted transforming collections...\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n\t\t\t\tconst document = await collection.transform(content, item, context);\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n\t\t\t\tcollection.data.get(id)!.document = document;\n\n\t\t\t\tdebug(`- Transformed item \"${id}\"...`);\n\t\t\t}\n\n\t\t\tdebug(\n\t\t\t\t`Done transforming ${String(collection.data.size)} item(s) in collection \"${collection.name}\".\\n`,\n\t\t\t);\n\t\t}\n\n\t\tif (signal?.aborted === true) {\n\t\t\tdebug(\"Aborted writing collections...\");\n\t\t\treturn;\n\t\t}\n\n\t\tfor (const collection of collections) {\n\t\t\tdebug(`Writing collection \"${collection.name}\"...`);\n\n\t\t\t// TODO: Consider combining serializing and writing to disk in one function.\n\t\t\tconst outputFilePath = path.join(collection.outputDirectoryPath, \"index.js\");\n\t\t\tconst [serialized, files] = serialize(collection.data);\n\t\t\tawait fs.writeFile(outputFilePath, serialized, { encoding: \"utf-8\" });\n\t\t\tfor (const [filePath, fileContent] of files) {\n\t\t\t\tconst outputFilePath = path.join(collection.outputDirectoryPath, filePath);\n\t\t\t\tawait fs.writeFile(outputFilePath, fileContent, { encoding: \"utf-8\" });\n\t\t\t}\n\t\t}\n\t}\n\n\tasync function build(): Promise<BuildStats> {\n\t\tdebug(\"Building...\\n\");\n\n\t\tfor (const collection of collections) {\n\t\t\tdebug(`Building collection \"${collection.name}\"...`);\n\n\t\t\t// eslint-disable-next-line n/no-unsupported-features/node-builtins\n\t\t\tfor await (const filePath of fs.glob(collection.include, {\n\t\t\t\tcwd: collection.directory,\n\t\t\t\texclude: collection.exclude,\n\t\t\t})) {\n\t\t\t\tconst absoluteFilePath = path.join(collection.directory, filePath);\n\t\t\t\tconst id = createIdFromFilePath(filePath);\n\n\t\t\t\tconst stats = await fs.stat(absoluteFilePath).catch((error: unknown) => {\n\t\t\t\t\tif (error instanceof Error && \"code\" in error && error.code === \"ENOENT\") {\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\tthrow error;\n\t\t\t\t});\n\t\t\t\tif (stats == null) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst { mtimeMs: timestamp } = stats;\n\n\t\t\t\tconst item: CollectionItem = { id, filePath, absoluteFilePath, timestamp };\n\n\t\t\t\tcollection.data.set(id, { item, content: null, document: null });\n\n\t\t\t\tdebug(`- Added item \"${id}\" (path: \"${filePath}\")...`);\n\t\t\t}\n\n\t\t\tdebug(\n\t\t\t\t`Done adding ${String(collection.data.size)} item(s) to collection \"${collection.name}\".\\n`,\n\t\t\t);\n\t\t}\n\n\t\tawait generate();\n\n\t\treturn {\n\t\t\tcollections: collections.length,\n\t\t\tdocuments: collections.reduce((acc, collection) => {\n\t\t\t\treturn acc + collection.data.size;\n\t\t\t}, 0),\n\t\t};\n\t}\n\n\tasync function watch(): Promise<Set<watcher.AsyncSubscription>> {\n\t\tdebug(\"Watching...\\n\");\n\n\t\tconst subscriptions = new Set<watcher.AsyncSubscription>();\n\n\t\tconst debounceDelayMs = 150;\n\t\tlet timer: ReturnType<typeof setTimeout> | null = null;\n\t\tlet controller: AbortController | null = null;\n\t\tlet batch = new Map<watcher.Event[\"path\"], watcher.Event & { relativeFilePath: string }>();\n\n\t\tfor (const collection of collections) {\n\t\t\tdebug(`Watching collection \"${collection.name}\"...`);\n\n\t\t\t/**\n\t\t\t * Ideally, we could just add `include` as a negative ignore pattern.\n\t\t\t *\n\t\t\t * This is currently not supported by `@parcel/watcher`. Simple patterns like \"!*.md\" do seem\n\t\t\t * to work, but others like \"!*\\/index.md\" do not.\n\t\t\t *\n\t\t\t * Therefore we need to filter out matching events in the javascript main thread\n\t\t\t * (see `path.matchesGlob` below).\n\t\t\t *\n\t\t\t * @see https://github.com/parcel-bundler/watcher/issues/166\n\t\t\t */\n\t\t\t// const ignore = [\n\t\t\t// \t...collection.include.map((glob) => {\n\t\t\t// \t\treturn `!${glob}`;\n\t\t\t// \t}),\n\t\t\t// \t...(collection.exclude ?? []),\n\t\t\t// ];\n\t\t\tconst ignore = (collection.exclude ?? []) as Array<string>;\n\n\t\t\tconst subscription = await watcher.subscribe(\n\t\t\t\tcollection.directory,\n\t\t\t\t(error, events) => {\n\t\t\t\t\tif (error != null) {\n\t\t\t\t\t\tlog.error(error);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tdebug(`- ${String(events.length)} events in collection \"${collection.name}\"...`);\n\n\t\t\t\t\tfor (const event of events) {\n\t\t\t\t\t\t// const relativeFilePath = path.relative(collection.directory, event.path);\n\t\t\t\t\t\tconst relativeFilePath = event.path.slice(collection.absoluteDirectoryPath.length);\n\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tcollection.include.some((pattern) => {\n\t\t\t\t\t\t\t\t// eslint-disable-next-line n/no-unsupported-features/node-builtins\n\t\t\t\t\t\t\t\treturn path.matchesGlob(relativeFilePath, pattern);\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t(event as watcher.Event & { relativeFilePath: string }).relativeFilePath =\n\t\t\t\t\t\t\t\trelativeFilePath;\n\t\t\t\t\t\t\tbatch.set(event.path, event as watcher.Event & { relativeFilePath: string });\n\n\t\t\t\t\t\t\tdebug(`- Added \"${event.type}\" event for \"${relativeFilePath}\" to queue.`);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tdebug(`- Discarded \"${event.type}\" event for \"${relativeFilePath}\".`);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (timer != null) {\n\t\t\t\t\t\tclearTimeout(timer);\n\t\t\t\t\t}\n\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-misused-promises\n\t\t\t\t\ttimer = setTimeout(async () => {\n\t\t\t\t\t\tif (controller != null) {\n\t\t\t\t\t\t\tcontroller.abort();\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcontroller = new AbortController();\n\n\t\t\t\t\t\tconst events = batch;\n\t\t\t\t\t\tbatch = new Map();\n\t\t\t\t\t\ttimer = null;\n\n\t\t\t\t\t\tlet isCollectionChanged = false;\n\n\t\t\t\t\t\tfor (const event of events.values()) {\n\t\t\t\t\t\t\tconst filePath = event.relativeFilePath;\n\t\t\t\t\t\t\tconst id = createIdFromFilePath(filePath);\n\n\t\t\t\t\t\t\tdebug(`Processing \"${event.type}\" event for \"${id}\".`);\n\n\t\t\t\t\t\t\tswitch (event.type) {\n\t\t\t\t\t\t\t\tcase \"create\":\n\t\t\t\t\t\t\t\tcase \"update\": {\n\t\t\t\t\t\t\t\t\tisCollectionChanged ||= event.type === \"create\" || collection.data.has(id);\n\n\t\t\t\t\t\t\t\t\tconst absoluteFilePath = path.join(collection.directory, filePath);\n\n\t\t\t\t\t\t\t\t\tconst stats = await fs.stat(absoluteFilePath).catch((error: unknown) => {\n\t\t\t\t\t\t\t\t\t\tif (error instanceof Error && \"code\" in error && error.code === \"ENOENT\") {\n\t\t\t\t\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\tif (stats == null) {\n\t\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tconst { mtimeMs: timestamp } = stats;\n\n\t\t\t\t\t\t\t\t\tconst item: CollectionItem = { id, filePath, absoluteFilePath, timestamp };\n\n\t\t\t\t\t\t\t\t\tcollection.data.set(id, { item, content: null, document: null });\n\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tcase \"delete\": {\n\t\t\t\t\t\t\t\t\tisCollectionChanged ||= collection.data.has(id);\n\n\t\t\t\t\t\t\t\t\tcollection.data.delete(id);\n\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (isCollectionChanged) {\n\t\t\t\t\t\t\tawait generate(controller.signal);\n\t\t\t\t\t\t}\n\t\t\t\t\t}, debounceDelayMs);\n\t\t\t\t},\n\t\t\t\t{ ignore },\n\t\t\t);\n\n\t\t\tsubscriptions.add(subscription);\n\t\t}\n\n\t\tasync function unsubscribe() {\n\t\t\tdebug(\"Cleaning up.\");\n\n\t\t\tif (timer != null) {\n\t\t\t\tclearTimeout(timer);\n\t\t\t}\n\t\t\ttimer = null;\n\n\t\t\tif (controller != null) {\n\t\t\t\tcontroller.abort();\n\t\t\t}\n\t\t\tcontroller = null;\n\n\t\t\tfor (const subscription of subscriptions) {\n\t\t\t\tawait subscription.unsubscribe();\n\t\t\t}\n\t\t\tsubscriptions.clear();\n\t\t}\n\n\t\t// eslint-disable-next-line @typescript-eslint/no-misused-promises\n\t\tprocess.once(\"SIGINT\", unsubscribe);\n\t\t// eslint-disable-next-line @typescript-eslint/no-misused-promises\n\t\tprocess.once(\"SIGTERM\", unsubscribe);\n\n\t\treturn subscriptions;\n\t}\n\n\treturn {\n\t\tbuild,\n\t\twatch,\n\t};\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["path","imports: Array<string>","value","collections: Array<Collection>","context: TransformContext","item: CollectionItem","timer: ReturnType<typeof setTimeout> | null","controller: AbortController | null","events","error"],"sources":["../src/index.ts"],"sourcesContent":["import * as crypto from \"node:crypto\";\nimport * as fs from \"node:fs/promises\";\nimport { availableParallelism } from \"node:os\";\nimport * as path from \"node:path\";\nimport { debuglog } from \"node:util\";\n\nimport { addTrailingSlash, log } from \"@acdh-oeaw/lib\";\nimport * as watcher from \"@parcel/watcher\";\nimport plimit from \"p-limit\";\n\n//\n\nconst debug = debuglog(\"content-lib\");\n\n//\n\nfunction createContentHash(value: string): string {\n\treturn crypto.createHash(\"sha256\").update(value).digest(\"hex\");\n}\n\nfunction createIdFromFilePath(filePath: string): string {\n\tconst parsed = path.parse(filePath);\n\n\tif (parsed.name.toLowerCase() === \"index\") {\n\t\treturn path.basename(parsed.dir);\n\t}\n\n\treturn parsed.name;\n}\n\n//\n\ntype MaybePromise<T> = T | Promise<T>;\n\ntype NonEmptyReadonlyArray<T> = readonly [T, ...Array<T>];\n\ntype GlobString = string;\n\ninterface CollectionItem {\n\t/** Unique identifier. */\n\tid: string;\n\t/** File path relative to colleciton directory. */\n\tfilePath: string;\n\t/** File path relative to current working directory. */\n\tabsoluteFilePath: string;\n\t/** File modification timestamp. */\n\ttimestamp: number;\n}\n\ninterface TransformContext {\n\tcreateImportDeclaration: (path: string) => ImportDeclaration;\n\tcreateJavaScriptImport: (content: string) => JavaScriptImport;\n\tcreateJsonImport: (content: string) => JsonImport;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport interface CollectionConfig<TCollectionItemContent = any, TCollectionDocument = any> {\n\tname: string;\n\tdirectory: string;\n\tinclude: NonEmptyReadonlyArray<GlobString>;\n\texclude?: ReadonlyArray<GlobString>;\n\tread: (item: CollectionItem) => MaybePromise<TCollectionItemContent>;\n\ttransform: (\n\t\tcontent: TCollectionItemContent,\n\t\titem: CollectionItem,\n\t\tcontext: TransformContext,\n\t) => MaybePromise<TCollectionDocument>;\n}\n\nexport function createCollection<TCollectionItemContent, TCollectionDocument>(\n\tconfig: CollectionConfig<TCollectionItemContent, TCollectionDocument>,\n): CollectionConfig<TCollectionItemContent, TCollectionDocument> {\n\treturn config;\n}\n\nexport interface ContentConfig {\n\tcollections: Array<CollectionConfig>;\n}\n\nexport function createConfig<T extends ContentConfig>(config: T): T {\n\treturn config;\n}\n\n//\n\n// function createItemCacheKey(item: CollectionItem): string {\n// \treturn String(item.timestamp);\n// }\n\n//\n\nclass ImportDeclaration {\n\tpath: string;\n\n\tconstructor(path: string) {\n\t\tthis.path = path;\n\t}\n}\n\nfunction createImportDeclaration(path: string): ImportDeclaration {\n\treturn new ImportDeclaration(path);\n}\n\nclass JavaScriptImport {\n\tcontent: string;\n\n\tconstructor(content: string) {\n\t\tthis.content = content;\n\t}\n}\n\nfunction createJavaScriptImport(content: string): JavaScriptImport {\n\treturn new JavaScriptImport(content);\n}\n\nclass JsonImport {\n\tcontent: string;\n\n\tconstructor(content: string) {\n\t\tthis.content = content;\n\t}\n}\n\nfunction createJsonImport(content: string): JsonImport {\n\treturn new JsonImport(content);\n}\n\n//\n\nconst prefix = \"__i__\";\nconst re = new RegExp(`\"(${prefix}\\\\d+)\"`, \"g\");\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction serialize(value: Map<string, any>): [string, Map<string, string>] {\n\tdebug(\"Serializing...\\n\");\n\n\tconst imports: Array<string> = [];\n\n\tfunction addImport(filePath: string, type: \"js\" | \"json\" = \"js\"): string {\n\t\tconst identifier = [prefix, imports.length].join(\"\");\n\t\timports.push(\n\t\t\t`import ${identifier} from \"${filePath}\"${type !== \"js\" ? ` with { type: \"${type}\" }` : \"\"};`,\n\t\t);\n\n\t\treturn identifier;\n\t}\n\n\tconst files = new Map<string, string>();\n\n\tfunction addFiles(filePath: string, content: string): void {\n\t\tfiles.set(filePath, content);\n\t}\n\n\tconst json = JSON.stringify(\n\t\tArray.from(value),\n\t\t// TODO: Should we support (multiple) named imports?\n\t\t(_key, value) => {\n\t\t\tif (value instanceof ImportDeclaration) {\n\t\t\t\tconst filePath = value.path;\n\n\t\t\t\tdebug(`Adding import declaration for \"${filePath}\".`);\n\t\t\t\tconst identifier = addImport(filePath);\n\n\t\t\t\treturn identifier;\n\t\t\t}\n\n\t\t\tif (value instanceof JavaScriptImport) {\n\t\t\t\tconst hash = createContentHash(value.content);\n\t\t\t\tconst filePath = `./${hash}.js`;\n\n\t\t\t\tdebug(`Adding javascript import for \"${filePath}\".`);\n\t\t\t\tconst identifier = addImport(filePath);\n\t\t\t\taddFiles(filePath, `// @ts-nocheck\\n${value.content}`);\n\n\t\t\t\treturn identifier;\n\t\t\t}\n\n\t\t\tif (value instanceof JsonImport) {\n\t\t\t\tconst hash = createContentHash(value.content);\n\t\t\t\tconst filePath = `./${hash}.json`;\n\n\t\t\t\tdebug(`Adding json import for \"${filePath}\".`);\n\t\t\t\tconst identifier = addImport(filePath, \"json\");\n\t\t\t\taddFiles(filePath, value.content);\n\n\t\t\t\treturn identifier;\n\t\t\t}\n\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return\n\t\t\treturn value;\n\t\t},\n\t\t2,\n\t)\n\t\t/** Remove quotes from import identifiers. */\n\t\t.replaceAll(re, \"$1\");\n\n\tlet result = \"\";\n\n\tif (imports.length > 0) {\n\t\tresult += imports.join(\"\\n\");\n\t\tresult += \"\\n\\n\";\n\t}\n\n\tresult += `const items = new Map(${json});\\n\\nexport default items;`;\n\n\treturn [result, files];\n}\n\n//\n\ninterface Collection extends CollectionConfig {\n\tabsoluteDirectoryPath: string;\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tdata: Map<CollectionItem[\"id\"], { item: CollectionItem; content: any; document: any }>; // TODO: revisit\n\toutputDirectoryPath: string;\n}\n\ninterface BuildStats {\n\tcollections: number;\n\tdocuments: number;\n}\n\nexport interface ContentProcessor {\n\tbuild: () => Promise<BuildStats>;\n\twatch: () => Promise<Set<watcher.AsyncSubscription>>;\n}\n\nexport async function createContentProcessor(config: ContentConfig): Promise<ContentProcessor> {\n\tdebug(\"Creating content processor...\\n\");\n\n\tconst concurrency = availableParallelism();\n\tconst limit = plimit(concurrency);\n\tdebug(`Concurrency: ${String(concurrency)}.\\n`);\n\n\tconst outputDirectoryBasePath = path.join(process.cwd(), \".content\", \"generated\");\n\n\tdebug(\"Clearing output directory...\\n\");\n\tawait fs.rm(outputDirectoryBasePath, { force: true, recursive: true });\n\n\tconst collections: Array<Collection> = [];\n\n\tconst context: TransformContext = {\n\t\tcreateImportDeclaration,\n\t\tcreateJavaScriptImport,\n\t\tcreateJsonImport,\n\t};\n\n\tfor (const collection of config.collections) {\n\t\tconst absoluteDirectoryPath = addTrailingSlash(path.resolve(collection.directory));\n\n\t\tconst outputDirectoryPath = path.join(\n\t\t\toutputDirectoryBasePath,\n\t\t\tcollection.name.toLowerCase().replaceAll(/[^a-z0-9_-]/g, \"-\"),\n\t\t);\n\t\tawait fs.mkdir(outputDirectoryPath, { recursive: true });\n\n\t\tcollections.push({\n\t\t\t...collection,\n\t\t\tabsoluteDirectoryPath,\n\t\t\tdata: new Map(),\n\t\t\toutputDirectoryPath,\n\t\t});\n\t}\n\n\tasync function generate(signal?: AbortSignal): Promise<void> {\n\t\tdebug(\"Generating...\\n\");\n\n\t\tfor (const collection of collections) {\n\t\t\tdebug(`Reading collection \"${collection.name}\"...`);\n\n\t\t\tawait limit.map(Array.from(collection.data), async ([id, { item }]) => {\n\t\t\t\tif (signal?.aborted === true) {\n\t\t\t\t\tdebug(\"Aborted reading collections.\");\n\t\t\t\t\tlimit.clearQueue();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// FIXME: race condition: what if file has been deleted in the meantime\n\t\t\t\t// TODO: skip item when `read()` returns `null`?\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n\t\t\t\tconst content = await collection.read(item);\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n\t\t\t\tcollection.data.get(id)!.content = content;\n\n\t\t\t\tdebug(`- Read item \"${id}\".`);\n\t\t\t});\n\n\t\t\tdebug(\n\t\t\t\t`Done reading ${String(collection.data.size)} item(s) in collection \"${collection.name}\".\\n`,\n\t\t\t);\n\t\t}\n\n\t\tfor (const collection of collections) {\n\t\t\tdebug(`Transforming collection \"${collection.name}\"...`);\n\n\t\t\tawait limit.map(Array.from(collection.data), async ([id, { content, item }]) => {\n\t\t\t\tif (signal?.aborted === true) {\n\t\t\t\t\tdebug(\"Aborted transforming collections.\");\n\t\t\t\t\tlimit.clearQueue();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n\t\t\t\tconst document = await collection.transform(content, item, context);\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n\t\t\t\tcollection.data.get(id)!.document = document;\n\n\t\t\t\tdebug(`- Transformed item \"${id}\".`);\n\t\t\t});\n\n\t\t\tdebug(\n\t\t\t\t`Done transforming ${String(collection.data.size)} item(s) in collection \"${collection.name}\".\\n`,\n\t\t\t);\n\t\t}\n\n\t\tif (signal?.aborted === true) {\n\t\t\tdebug(\"Aborted writing collections.\");\n\t\t\treturn;\n\t\t}\n\n\t\tfor (const collection of collections) {\n\t\t\tdebug(`Writing collection \"${collection.name}\".`);\n\n\t\t\t// TODO: Consider combining serializing and writing to disk in one function.\n\t\t\tconst [serialized, files] = serialize(collection.data);\n\t\t\tfiles.set(\"index.js\", serialized);\n\n\t\t\tawait limit.map(Array.from(files), async ([filePath, fileContent]) => {\n\t\t\t\tconst outputFilePath = path.join(collection.outputDirectoryPath, filePath);\n\t\t\t\tawait fs.writeFile(outputFilePath, fileContent, { encoding: \"utf-8\" });\n\t\t\t});\n\t\t}\n\t}\n\n\tasync function build(): Promise<BuildStats> {\n\t\tdebug(\"Building...\\n\");\n\n\t\tfor (const collection of collections) {\n\t\t\tdebug(`Building collection \"${collection.name}\"...`);\n\n\t\t\t// eslint-disable-next-line n/no-unsupported-features/node-builtins\n\t\t\tfor await (const filePath of fs.glob(collection.include, {\n\t\t\t\tcwd: collection.directory,\n\t\t\t\texclude: collection.exclude,\n\t\t\t})) {\n\t\t\t\tconst absoluteFilePath = path.join(collection.directory, filePath);\n\t\t\t\tconst id = createIdFromFilePath(filePath);\n\n\t\t\t\tconst stats = await fs.stat(absoluteFilePath).catch((error: unknown) => {\n\t\t\t\t\tif (error instanceof Error && \"code\" in error && error.code === \"ENOENT\") {\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\tthrow error;\n\t\t\t\t});\n\t\t\t\tif (stats == null) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst { mtimeMs: timestamp } = stats;\n\n\t\t\t\tconst item: CollectionItem = { id, filePath, absoluteFilePath, timestamp };\n\n\t\t\t\tcollection.data.set(id, { item, content: null, document: null });\n\n\t\t\t\tdebug(`- Added item \"${id}\" (path: \"${filePath}\").`);\n\t\t\t}\n\n\t\t\tdebug(\n\t\t\t\t`Done adding ${String(collection.data.size)} item(s) to collection \"${collection.name}\".\\n`,\n\t\t\t);\n\t\t}\n\n\t\tawait generate();\n\n\t\treturn {\n\t\t\tcollections: collections.length,\n\t\t\tdocuments: collections.reduce((acc, collection) => {\n\t\t\t\treturn acc + collection.data.size;\n\t\t\t}, 0),\n\t\t};\n\t}\n\n\tasync function watch(): Promise<Set<watcher.AsyncSubscription>> {\n\t\tdebug(\"Watching...\\n\");\n\n\t\tconst subscriptions = new Set<watcher.AsyncSubscription>();\n\n\t\tconst debounceDelayMs = 150;\n\t\tlet timer: ReturnType<typeof setTimeout> | null = null;\n\t\tlet controller: AbortController | null = null;\n\t\tlet batch = new Map<watcher.Event[\"path\"], watcher.Event & { relativeFilePath: string }>();\n\n\t\tfor (const collection of collections) {\n\t\t\tdebug(`Watching collection \"${collection.name}\"...`);\n\n\t\t\t/**\n\t\t\t * Ideally, we could just add `include` as a negative ignore pattern.\n\t\t\t *\n\t\t\t * This is currently not supported by `@parcel/watcher`. Simple patterns like \"!*.md\" do seem\n\t\t\t * to work, but others like \"!*\\/index.md\" do not.\n\t\t\t *\n\t\t\t * Therefore we need to filter out matching events in the javascript main thread\n\t\t\t * (see `path.matchesGlob` below).\n\t\t\t *\n\t\t\t * @see https://github.com/parcel-bundler/watcher/issues/166\n\t\t\t */\n\t\t\t// const ignore = [\n\t\t\t// \t...collection.include.map((glob) => {\n\t\t\t// \t\treturn `!${glob}`;\n\t\t\t// \t}),\n\t\t\t// \t...(collection.exclude ?? []),\n\t\t\t// ];\n\t\t\tconst ignore = (collection.exclude ?? []) as Array<string>;\n\n\t\t\tconst subscription = await watcher.subscribe(\n\t\t\t\tcollection.directory,\n\t\t\t\t(error, events) => {\n\t\t\t\t\tif (error != null) {\n\t\t\t\t\t\tlog.error(error);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tdebug(`- ${String(events.length)} events in collection \"${collection.name}\".`);\n\n\t\t\t\t\tfor (const event of events) {\n\t\t\t\t\t\t// const relativeFilePath = path.relative(collection.directory, event.path);\n\t\t\t\t\t\tconst relativeFilePath = event.path.slice(collection.absoluteDirectoryPath.length);\n\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tcollection.include.some((pattern) => {\n\t\t\t\t\t\t\t\t// eslint-disable-next-line n/no-unsupported-features/node-builtins\n\t\t\t\t\t\t\t\treturn path.matchesGlob(relativeFilePath, pattern);\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t(event as watcher.Event & { relativeFilePath: string }).relativeFilePath =\n\t\t\t\t\t\t\t\trelativeFilePath;\n\t\t\t\t\t\t\tbatch.set(event.path, event as watcher.Event & { relativeFilePath: string });\n\n\t\t\t\t\t\t\tdebug(`- Added \"${event.type}\" event for \"${relativeFilePath}\" to queue.`);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tdebug(`- Discarded \"${event.type}\" event for \"${relativeFilePath}\".`);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (timer != null) {\n\t\t\t\t\t\tclearTimeout(timer);\n\t\t\t\t\t}\n\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-misused-promises\n\t\t\t\t\ttimer = setTimeout(async () => {\n\t\t\t\t\t\tif (controller != null) {\n\t\t\t\t\t\t\tcontroller.abort();\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcontroller = new AbortController();\n\n\t\t\t\t\t\tconst events = batch;\n\t\t\t\t\t\tbatch = new Map();\n\t\t\t\t\t\ttimer = null;\n\n\t\t\t\t\t\tlet isCollectionChanged = false;\n\n\t\t\t\t\t\tfor (const event of events.values()) {\n\t\t\t\t\t\t\tconst filePath = event.relativeFilePath;\n\t\t\t\t\t\t\tconst id = createIdFromFilePath(filePath);\n\n\t\t\t\t\t\t\tdebug(`Processing \"${event.type}\" event for \"${id}\".`);\n\n\t\t\t\t\t\t\tswitch (event.type) {\n\t\t\t\t\t\t\t\tcase \"create\":\n\t\t\t\t\t\t\t\tcase \"update\": {\n\t\t\t\t\t\t\t\t\tisCollectionChanged ||= event.type === \"create\" || collection.data.has(id);\n\n\t\t\t\t\t\t\t\t\tconst absoluteFilePath = path.join(collection.directory, filePath);\n\n\t\t\t\t\t\t\t\t\tconst stats = await fs.stat(absoluteFilePath).catch((error: unknown) => {\n\t\t\t\t\t\t\t\t\t\tif (error instanceof Error && \"code\" in error && error.code === \"ENOENT\") {\n\t\t\t\t\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\tif (stats == null) {\n\t\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tconst { mtimeMs: timestamp } = stats;\n\n\t\t\t\t\t\t\t\t\tconst item: CollectionItem = { id, filePath, absoluteFilePath, timestamp };\n\n\t\t\t\t\t\t\t\t\tcollection.data.set(id, { item, content: null, document: null });\n\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tcase \"delete\": {\n\t\t\t\t\t\t\t\t\tisCollectionChanged ||= collection.data.has(id);\n\n\t\t\t\t\t\t\t\t\tcollection.data.delete(id);\n\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (isCollectionChanged) {\n\t\t\t\t\t\t\tawait generate(controller.signal);\n\t\t\t\t\t\t}\n\t\t\t\t\t}, debounceDelayMs);\n\t\t\t\t},\n\t\t\t\t{ ignore },\n\t\t\t);\n\n\t\t\tsubscriptions.add(subscription);\n\t\t}\n\n\t\tasync function unsubscribe() {\n\t\t\tdebug(\"Cleaning up...\");\n\n\t\t\tif (timer != null) {\n\t\t\t\tclearTimeout(timer);\n\t\t\t}\n\t\t\ttimer = null;\n\n\t\t\tif (controller != null) {\n\t\t\t\tcontroller.abort();\n\t\t\t}\n\t\t\tcontroller = null;\n\n\t\t\tfor (const subscription of subscriptions) {\n\t\t\t\tawait subscription.unsubscribe();\n\t\t\t}\n\t\t\tsubscriptions.clear();\n\t\t}\n\n\t\t// eslint-disable-next-line @typescript-eslint/no-misused-promises\n\t\tprocess.once(\"SIGINT\", unsubscribe);\n\t\t// eslint-disable-next-line @typescript-eslint/no-misused-promises\n\t\tprocess.once(\"SIGTERM\", unsubscribe);\n\n\t\treturn subscriptions;\n\t}\n\n\treturn {\n\t\tbuild,\n\t\twatch,\n\t};\n}\n"],"mappings":";;;;;;;;;;AAYA,MAAM,QAAQ,SAAS;AAIvB,SAAS,kBAAkB,OAAuB;AACjD,QAAO,OAAO,WAAW,UAAU,OAAO,OAAO,OAAO;AACxD;AAED,SAAS,qBAAqB,UAA0B;CACvD,MAAM,SAAS,KAAK,MAAM;AAE1B,KAAI,OAAO,KAAK,kBAAkB,QACjC,QAAO,KAAK,SAAS,OAAO;AAG7B,QAAO,OAAO;AACd;AAyCD,SAAgB,iBACf,QACgE;AAChE,QAAO;AACP;AAMD,SAAgB,aAAsC,QAAc;AACnE,QAAO;AACP;AAUD,IAAM,oBAAN,MAAwB;CACvB;CAEA,YAAY,QAAc;AACzB,OAAK,OAAOA;CACZ;AACD;AAED,SAAS,wBAAwB,QAAiC;AACjE,QAAO,IAAI,kBAAkBA;AAC7B;AAED,IAAM,mBAAN,MAAuB;CACtB;CAEA,YAAY,SAAiB;AAC5B,OAAK,UAAU;CACf;AACD;AAED,SAAS,uBAAuB,SAAmC;AAClE,QAAO,IAAI,iBAAiB;AAC5B;AAED,IAAM,aAAN,MAAiB;CAChB;CAEA,YAAY,SAAiB;AAC5B,OAAK,UAAU;CACf;AACD;AAED,SAAS,iBAAiB,SAA6B;AACtD,QAAO,IAAI,WAAW;AACtB;AAID,MAAM,SAAS;AACf,MAAM,KAAK,IAAI,OAAO,KAAK,OAAO,SAAS;AAG3C,SAAS,UAAU,OAAwD;AAC1E,OAAM;CAEN,MAAMC,UAAyB,EAAE;CAEjC,SAAS,UAAU,UAAkB,OAAsB,MAAc;EACxE,MAAM,aAAa,CAAC,QAAQ,QAAQ,OAAO,CAAC,KAAK;AACjD,UAAQ,KACP,UAAU,WAAW,SAAS,SAAS,GAAG,SAAS,OAAO,kBAAkB,KAAK,OAAO,GAAG;AAG5F,SAAO;CACP;CAED,MAAM,wBAAQ,IAAI;CAElB,SAAS,SAAS,UAAkB,SAAuB;AAC1D,QAAM,IAAI,UAAU;CACpB;CAED,MAAM,OAAO,KAAK,UACjB,MAAM,KAAK,SAEV,MAAM,YAAU;AAChB,MAAIC,mBAAiB,mBAAmB;GACvC,MAAM,WAAWA,QAAM;AAEvB,SAAM,kCAAkC,SAAS;GACjD,MAAM,aAAa,UAAU;AAE7B,UAAO;EACP;AAED,MAAIA,mBAAiB,kBAAkB;GACtC,MAAM,OAAO,kBAAkBA,QAAM;GACrC,MAAM,WAAW,KAAK,KAAK;AAE3B,SAAM,iCAAiC,SAAS;GAChD,MAAM,aAAa,UAAU;AAC7B,YAAS,UAAU,mBAAmBA,QAAM;AAE5C,UAAO;EACP;AAED,MAAIA,mBAAiB,YAAY;GAChC,MAAM,OAAO,kBAAkBA,QAAM;GACrC,MAAM,WAAW,KAAK,KAAK;AAE3B,SAAM,2BAA2B,SAAS;GAC1C,MAAM,aAAa,UAAU,UAAU;AACvC,YAAS,UAAUA,QAAM;AAEzB,UAAO;EACP;AAGD,SAAOA;CACP,GACD,GAGC,WAAW,IAAI;CAEjB,IAAI,SAAS;AAEb,KAAI,QAAQ,SAAS,GAAG;AACvB,YAAU,QAAQ,KAAK;AACvB,YAAU;CACV;AAED,WAAU,yBAAyB,KAAK;AAExC,QAAO,CAAC,QAAQ,MAAM;AACtB;AAqBD,eAAsB,uBAAuB,QAAkD;AAC9F,OAAM;CAEN,MAAM,cAAc;CACpB,MAAM,QAAQ,OAAO;AACrB,OAAM,gBAAgB,OAAO,aAAa;CAE1C,MAAM,0BAA0B,KAAK,KAAK,QAAQ,OAAO,YAAY;AAErE,OAAM;AACN,OAAM,GAAG,GAAG,yBAAyB;EAAE,OAAO;EAAM,WAAW;EAAM;CAErE,MAAMC,cAAiC,EAAE;CAEzC,MAAMC,UAA4B;EACjC;EACA;EACA;EACA;AAED,MAAK,MAAM,cAAc,OAAO,aAAa;EAC5C,MAAM,wBAAwB,iBAAiB,KAAK,QAAQ,WAAW;EAEvE,MAAM,sBAAsB,KAAK,KAChC,yBACA,WAAW,KAAK,cAAc,WAAW,gBAAgB;AAE1D,QAAM,GAAG,MAAM,qBAAqB,EAAE,WAAW,MAAM;AAEvD,cAAY,KAAK;GAChB,GAAG;GACH;GACA,sBAAM,IAAI;GACV;GACA;CACD;CAED,eAAe,SAAS,QAAqC;AAC5D,QAAM;AAEN,OAAK,MAAM,cAAc,aAAa;AACrC,SAAM,uBAAuB,WAAW,KAAK;AAE7C,SAAM,MAAM,IAAI,MAAM,KAAK,WAAW,OAAO,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK;AACtE,QAAI,QAAQ,YAAY,MAAM;AAC7B,WAAM;AACN,WAAM;AACN;IACA;IAKD,MAAM,UAAU,MAAM,WAAW,KAAK;AAEtC,eAAW,KAAK,IAAI,IAAK,UAAU;AAEnC,UAAM,gBAAgB,GAAG;GACzB;AAED,SACC,gBAAgB,OAAO,WAAW,KAAK,MAAM,0BAA0B,WAAW,KAAK;EAExF;AAED,OAAK,MAAM,cAAc,aAAa;AACrC,SAAM,4BAA4B,WAAW,KAAK;AAElD,SAAM,MAAM,IAAI,MAAM,KAAK,WAAW,OAAO,OAAO,CAAC,IAAI,EAAE,SAAS,MAAM,CAAC,KAAK;AAC/E,QAAI,QAAQ,YAAY,MAAM;AAC7B,WAAM;AACN,WAAM;AACN;IACA;IAGD,MAAM,WAAW,MAAM,WAAW,UAAU,SAAS,MAAM;AAE3D,eAAW,KAAK,IAAI,IAAK,WAAW;AAEpC,UAAM,uBAAuB,GAAG;GAChC;AAED,SACC,qBAAqB,OAAO,WAAW,KAAK,MAAM,0BAA0B,WAAW,KAAK;EAE7F;AAED,MAAI,QAAQ,YAAY,MAAM;AAC7B,SAAM;AACN;EACA;AAED,OAAK,MAAM,cAAc,aAAa;AACrC,SAAM,uBAAuB,WAAW,KAAK;GAG7C,MAAM,CAAC,YAAY,MAAM,GAAG,UAAU,WAAW;AACjD,SAAM,IAAI,YAAY;AAEtB,SAAM,MAAM,IAAI,MAAM,KAAK,QAAQ,OAAO,CAAC,UAAU,YAAY,KAAK;IACrE,MAAM,iBAAiB,KAAK,KAAK,WAAW,qBAAqB;AACjE,UAAM,GAAG,UAAU,gBAAgB,aAAa,EAAE,UAAU,SAAS;GACrE;EACD;CACD;CAED,eAAe,QAA6B;AAC3C,QAAM;AAEN,OAAK,MAAM,cAAc,aAAa;AACrC,SAAM,wBAAwB,WAAW,KAAK;AAG9C,cAAW,MAAM,YAAY,GAAG,KAAK,WAAW,SAAS;IACxD,KAAK,WAAW;IAChB,SAAS,WAAW;IACpB,GAAG;IACH,MAAM,mBAAmB,KAAK,KAAK,WAAW,WAAW;IACzD,MAAM,KAAK,qBAAqB;IAEhC,MAAM,QAAQ,MAAM,GAAG,KAAK,kBAAkB,OAAO,UAAmB;AACvE,SAAI,iBAAiB,SAAS,UAAU,SAAS,MAAM,SAAS,SAC/D,QAAO;AAER,WAAM;IACN;AACD,QAAI,SAAS,KACZ;IAED,MAAM,EAAE,SAAS,WAAW,GAAG;IAE/B,MAAMC,OAAuB;KAAE;KAAI;KAAU;KAAkB;KAAW;AAE1E,eAAW,KAAK,IAAI,IAAI;KAAE;KAAM,SAAS;KAAM,UAAU;KAAM;AAE/D,UAAM,iBAAiB,GAAG,YAAY,SAAS;GAC/C;AAED,SACC,eAAe,OAAO,WAAW,KAAK,MAAM,0BAA0B,WAAW,KAAK;EAEvF;AAED,QAAM;AAEN,SAAO;GACN,aAAa,YAAY;GACzB,WAAW,YAAY,QAAQ,KAAK,eAAe;AAClD,WAAO,MAAM,WAAW,KAAK;GAC7B,GAAE;GACH;CACD;CAED,eAAe,QAAiD;AAC/D,QAAM;EAEN,MAAM,gCAAgB,IAAI;EAE1B,MAAM,kBAAkB;EACxB,IAAIC,QAA8C;EAClD,IAAIC,aAAqC;EACzC,IAAI,wBAAQ,IAAI;AAEhB,OAAK,MAAM,cAAc,aAAa;AACrC,SAAM,wBAAwB,WAAW,KAAK;;;;;;;;;;;;GAmB9C,MAAM,SAAU,WAAW,WAAW,EAAE;GAExC,MAAM,eAAe,MAAM,QAAQ,UAClC,WAAW,YACV,OAAO,WAAW;AAClB,QAAI,SAAS,MAAM;AAClB,SAAI,MAAM;AACV;IACA;AAED,UAAM,KAAK,OAAO,OAAO,QAAQ,yBAAyB,WAAW,KAAK;AAE1E,SAAK,MAAM,SAAS,QAAQ;KAE3B,MAAM,mBAAmB,MAAM,KAAK,MAAM,WAAW,sBAAsB;AAE3E,SACC,WAAW,QAAQ,MAAM,YAAY;AAEpC,aAAO,KAAK,YAAY,kBAAkB;KAC1C,IACA;AACD,MAAC,MAAuD,mBACvD;AACD,YAAM,IAAI,MAAM,MAAM;AAEtB,YAAM,YAAY,MAAM,KAAK,eAAe,iBAAiB;KAC7D,MACA,OAAM,gBAAgB,MAAM,KAAK,eAAe,iBAAiB;IAElE;AAED,QAAI,SAAS,KACZ,cAAa;AAId,YAAQ,WAAW,YAAY;AAC9B,SAAI,cAAc,KACjB,YAAW;AAGZ,kBAAa,IAAI;KAEjB,MAAMC,WAAS;AACf,6BAAQ,IAAI;AACZ,aAAQ;KAER,IAAI,sBAAsB;AAE1B,UAAK,MAAM,SAASA,SAAO,UAAU;MACpC,MAAM,WAAW,MAAM;MACvB,MAAM,KAAK,qBAAqB;AAEhC,YAAM,eAAe,MAAM,KAAK,eAAe,GAAG;AAElD,cAAQ,MAAM,MAAd;OACC,KAAK;OACL,KAAK,UAAU;AACd,gCAAwB,MAAM,SAAS,YAAY,WAAW,KAAK,IAAI;QAEvE,MAAM,mBAAmB,KAAK,KAAK,WAAW,WAAW;QAEzD,MAAM,QAAQ,MAAM,GAAG,KAAK,kBAAkB,OAAO,YAAmB;AACvE,aAAIC,mBAAiB,SAAS,UAAUA,WAASA,QAAM,SAAS,SAC/D,QAAO;AAER,eAAMA;QACN;AACD,YAAI,SAAS,KACZ;QAED,MAAM,EAAE,SAAS,WAAW,GAAG;QAE/B,MAAMJ,OAAuB;SAAE;SAAI;SAAU;SAAkB;SAAW;AAE1E,mBAAW,KAAK,IAAI,IAAI;SAAE;SAAM,SAAS;SAAM,UAAU;SAAM;AAE/D;OACA;OAED,KAAK;AACJ,gCAAwB,WAAW,KAAK,IAAI;AAE5C,mBAAW,KAAK,OAAO;AAEvB;MAED;KACD;AAED,SAAI,oBACH,OAAM,SAAS,WAAW;IAE3B,GAAE;GACH,GACD,EAAE,QAAQ;AAGX,iBAAc,IAAI;EAClB;EAED,eAAe,cAAc;AAC5B,SAAM;AAEN,OAAI,SAAS,KACZ,cAAa;AAEd,WAAQ;AAER,OAAI,cAAc,KACjB,YAAW;AAEZ,gBAAa;AAEb,QAAK,MAAM,gBAAgB,cAC1B,OAAM,aAAa;AAEpB,iBAAc;EACd;AAGD,UAAQ,KAAK,UAAU;AAEvB,UAAQ,KAAK,WAAW;AAExB,SAAO;CACP;AAED,QAAO;EACN;EACA;EACA;AACD"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@acdh-oeaw/content-lib",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -22,7 +22,8 @@
|
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@acdh-oeaw/lib": "0.3.4",
|
|
25
|
-
"@parcel/watcher": "^2.5.1"
|
|
25
|
+
"@parcel/watcher": "^2.5.1",
|
|
26
|
+
"p-limit": "^7.0.0"
|
|
26
27
|
},
|
|
27
28
|
"devDependencies": {
|
|
28
29
|
"@acdh-oeaw/eslint-config": "2.0.9",
|