@riboseinc/anafero-cli 0.0.66 → 0.0.68

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-site.mjs CHANGED
@@ -294425,7 +294425,88 @@ function makeDummyInMemoryCache() {
294425
294425
  throw new Error("Requested key does not exist");
294426
294426
  }
294427
294427
  },
294428
- dump: () => cache3
294428
+ dump: async (stream4, signal) => {
294429
+ async function* buildKeypaths(obj, currentPath, seen, paths2, signal2) {
294430
+ if (signal2.aborted) {
294431
+ throw new Error("Aborted");
294432
+ }
294433
+ for (const key of Object.keys(Object(obj))) {
294434
+ const val = obj[key];
294435
+ if (typeof val === "string" || Object.keys(Object(val)).length === 0) {
294436
+ yield [...currentPath, key];
294437
+ } else {
294438
+ const complexVal = val;
294439
+ if (!seen.has(complexVal)) {
294440
+ seen.add(complexVal);
294441
+ yield* buildKeypaths(
294442
+ complexVal,
294443
+ [...currentPath, key],
294444
+ seen,
294445
+ paths2,
294446
+ signal2
294447
+ );
294448
+ }
294449
+ }
294450
+ }
294451
+ }
294452
+ async function write4(data, end6) {
294453
+ return new Promise((resolve4) => {
294454
+ if (end6) {
294455
+ stream4.end(data, function() {
294456
+ resolve4();
294457
+ });
294458
+ } else {
294459
+ stream4.write(data, function() {
294460
+ resolve4();
294461
+ });
294462
+ }
294463
+ });
294464
+ }
294465
+ function serializeKeypath(idx2, keyPaths) {
294466
+ const keyPath = keyPaths[idx2];
294467
+ if (keyPath) {
294468
+ const keyString = keyPath.join(".");
294469
+ keyPath.reverse();
294470
+ let valueCursor = cache3;
294471
+ while (true) {
294472
+ let part = keyPath.pop();
294473
+ if (part) {
294474
+ valueCursor = valueCursor[part];
294475
+ } else {
294476
+ break;
294477
+ }
294478
+ }
294479
+ return `
294480
+ ${JSON.stringify(keyString)}: ${valueCursor}`;
294481
+ } else {
294482
+ return null;
294483
+ }
294484
+ }
294485
+ const pathGen = buildKeypaths(cache3, [], /* @__PURE__ */ new Set(), [], signal);
294486
+ const paths = [];
294487
+ for await (const p3 of pathGen) {
294488
+ paths.push(p3);
294489
+ }
294490
+ await write4(`
294491
+ -- starting dumping ${paths.length} paths --`);
294492
+ let idx = 0;
294493
+ const chunkSize = 1e3;
294494
+ let chunk4 = "";
294495
+ while (true) {
294496
+ if (idx > 0 && idx % chunkSize === 0) {
294497
+ await write4(chunk4);
294498
+ chunk4 = "";
294499
+ }
294500
+ const nextItem = serializeKeypath(idx, paths);
294501
+ if (nextItem) {
294502
+ chunk4 = chunk4 + nextItem;
294503
+ } else {
294504
+ break;
294505
+ }
294506
+ idx += 1;
294507
+ }
294508
+ return;
294509
+ }
294429
294510
  };
294430
294511
  }
294431
294512
 
@@ -313425,6 +313506,11 @@ var BuildConfigSchema = Struct({
313425
313506
  version: Literal4("0.1"),
313426
313507
  /** The entry point, path to XML of a Metanorma document or collection. */
313427
313508
  entryPoint: String$2.pipe(nonEmptyString4()),
313509
+ /**
313510
+ * Workspace title.
313511
+ * If not provided, “document ID • document title” is used.
313512
+ */
313513
+ workspaceTitle: String$2.pipe(nonEmptyString4()).pipe(optional),
313428
313514
  /**
313429
313515
  * Which reader modules to use.
313430
313516
  *
@@ -313648,12 +313734,48 @@ function getTextContent(graph, subject, partPredicate) {
313648
313734
  // ../anafero/search.mts
313649
313735
  init_cjs_shim();
313650
313736
  function preprocessStringForIndexing(text9) {
313651
- return text9.normalize("NFKD").replace(/\p{Diacritic}/gu, "").trim();
313737
+ return text9.normalize("NFKD").replace(/\p{Diacritic}/gu, "").replace(/[\p{P}$+<=>^`|~]/gu, " ").replace(/[\u200B-\u200D\uFEFF]/g, "").trim();
313652
313738
  }
313653
- function extractRelationsForIndexing(uri, graph, isDefinedSubject) {
313654
- return graph.filter(
313655
- ([s2, p3, o2]) => p3 === "hasPart" && (s2 === uri || s2 === ROOT_SUBJECT) && !o2.startsWith("data:") && (!isURIString(o2) || !isDefinedSubject(o2))
313739
+ function extractRelationsForIndexing(uri, graph, isIndexable, isAlreadyIndexed, _seen, _log) {
313740
+ const seen = _seen ?? /* @__PURE__ */ new Set();
313741
+ seen.add(uri);
313742
+ const nonData = graph.filter(
313743
+ ([, , o2]) => !o2.startsWith("data:")
313744
+ );
313745
+ const immediateGraph = nonData.filter(
313746
+ ([s2, ,]) => s2 === uri || s2 === ROOT_SUBJECT
313656
313747
  );
313748
+ const references = immediateGraph.filter(
313749
+ ([, , o2]) => isURIString(o2)
313750
+ );
313751
+ const indexable = immediateGraph.filter(
313752
+ ([s2, p3, o2]) => !isURIString(o2) && isIndexable([s2, p3, o2])
313753
+ ).map(([, , o2]) => o2).filter((o2) => o2.trim() !== "");
313754
+ for (const [, , o2] of references) {
313755
+ if (_log) {
313756
+ console.debug(
313757
+ "search: processing triple object",
313758
+ { o: o2, isAlreadyIndexed: isAlreadyIndexed(o2) }
313759
+ );
313760
+ }
313761
+ if (!isAlreadyIndexed(o2) && !seen.has(o2)) {
313762
+ indexable.push(...extractRelationsForIndexing(
313763
+ o2,
313764
+ graph,
313765
+ isIndexable,
313766
+ isAlreadyIndexed,
313767
+ seen,
313768
+ _log
313769
+ ));
313770
+ }
313771
+ }
313772
+ if (_log) {
313773
+ console.debug(
313774
+ "search: obtained indexable from graph",
313775
+ { uri, graph, indexable }
313776
+ );
313777
+ }
313778
+ return indexable;
313657
313779
  }
313658
313780
 
313659
313781
  // ../anafero-gui/loader.mts
@@ -317589,7 +317711,7 @@ ${inject.head ?? ""}`;
317589
317711
  const assetsToWrite = {};
317590
317712
  const rootMeta = reader.describeRoot();
317591
317713
  const maybePrimaryLanguageID = rootMeta.primaryLanguageID ?? "en";
317592
- const maybeMainTitle = rootMeta.labelInPlainText ?? "Document";
317714
+ const maybeMainTitle = cfg.workspaceTitle ?? rootMeta.labelInPlainText ?? "Document";
317593
317715
  const allLanguages = /* @__PURE__ */ new Set(["en"]);
317594
317716
  function getReverseResourceMap() {
317595
317717
  return Object.fromEntries(Object.entries(resourceMap).map(([k, v]) => [v, k]));
@@ -317656,41 +317778,66 @@ ${inject.head ?? ""}`;
317656
317778
  );
317657
317779
  pathProgress({ state: "updating artifacts" });
317658
317780
  if (content?.content) {
317781
+ let isIndexable2 = function(rel) {
317782
+ return rel[1] === "hasPart";
317783
+ }, isIndexed2 = function(uri) {
317784
+ return reader.exists(uri) && describedResourceIDs.has(uri);
317785
+ };
317786
+ var isIndexable = isIndexable2, isIndexed = isIndexed2;
317659
317787
  if (meta.primaryLanguageID) {
317660
317788
  allLanguages.add(meta.primaryLanguageID);
317661
317789
  }
317662
317790
  pathProgress({ state: "indexing page resource" });
317791
+ const describedResourceIDs = gatherDescribedResourcesFromJsonifiedProseMirrorNode(
317792
+ content.content.contentDoc
317793
+ );
317663
317794
  resourceMap[path3] = resourceURI;
317664
- resourceGraph.push([resourceURI, "isDefinedBy", `${path3}/resource.json`]);
317795
+ resourceGraph.push([
317796
+ resourceURI,
317797
+ "isDefinedBy",
317798
+ `${path3}/resource.json`
317799
+ ]);
317665
317800
  resourceDescriptions[resourceURI] = resourceMeta;
317666
317801
  searchableResources.pages[resourceURI] = {
317667
317802
  name: resourceURI,
317668
317803
  title: preprocessStringForIndexing(meta.labelInPlainText),
317669
317804
  lang: meta.primaryLanguageID || "",
317670
317805
  body: preprocessStringForIndexing(
317671
- extractRelationsForIndexing(resourceURI, relations, reader.exists).join("").trim()
317806
+ extractRelationsForIndexing(
317807
+ resourceURI,
317808
+ relations,
317809
+ isIndexable2,
317810
+ isIndexed2
317811
+ ).join("\n").trim()
317672
317812
  )
317673
317813
  };
317674
317814
  pathProgress({ state: "indexing on-page subresources" });
317675
- const describedResourceIDs = gatherDescribedResourcesFromJsonifiedProseMirrorNode(
317676
- content.content.contentDoc
317677
- );
317678
317815
  for (const inPageResourceID of describedResourceIDs) {
317679
317816
  if (reader.exists(inPageResourceID)) {
317680
317817
  const pathWithFragment = `${path3}#${encodeURIComponent(inPageResourceID)}`;
317681
317818
  const meta2 = reader.describe(inPageResourceID);
317682
317819
  const graph2 = reader.resolve(inPageResourceID);
317683
317820
  resourceMap[pathWithFragment] = inPageResourceID;
317684
- resourceGraph.push([inPageResourceID, "isDefinedBy", `${path3}/resource.json`]);
317821
+ resourceGraph.push([
317822
+ inPageResourceID,
317823
+ "isDefinedBy",
317824
+ `${path3}/resource.json`
317825
+ ]);
317685
317826
  resourceDescriptions[inPageResourceID] = meta2;
317686
317827
  if (inPageResourceID !== resourceURI) {
317828
+ const body = preprocessStringForIndexing(
317829
+ extractRelationsForIndexing(
317830
+ inPageResourceID,
317831
+ graph2,
317832
+ isIndexable2,
317833
+ isIndexed2
317834
+ ).join("\n").trim()
317835
+ );
317687
317836
  searchableResources.resources[inPageResourceID] = {
317688
317837
  name: inPageResourceID,
317689
317838
  title: preprocessStringForIndexing(meta2.labelInPlainText),
317690
317839
  lang: meta2.primaryLanguageID || "",
317691
- body: preprocessStringForIndexing(
317692
- extractRelationsForIndexing(inPageResourceID, graph2, reader.exists).join("").trim()
317693
- )
317840
+ body
317694
317841
  };
317695
317842
  }
317696
317843
  } else {
@@ -317785,7 +317932,7 @@ ${inject.head ?? ""}`;
317785
317932
  supportedLanguages.join(", ")
317786
317933
  );
317787
317934
  const lunrTokenizer = import_lunr.default.tokenizer;
317788
- this.tokenizer = function(x2) {
317935
+ this.tokenizer = function anaferoTokenizer(x2) {
317789
317936
  const baseLunrTokens = lunrTokenizer(x2);
317790
317937
  const tokens = [...baseLunrTokens];
317791
317938
  for (const lang of nonDefaultLanguages) {
@@ -317801,7 +317948,7 @@ ${inject.head ?? ""}`;
317801
317948
  return tokens;
317802
317949
  };
317803
317950
  const lunrStopWordFilter = import_lunr.default.stopWordFilter;
317804
- this.stopWordFilter = function(token) {
317951
+ this.stopWordFilter = function anaferoStopWordFilter(token) {
317805
317952
  return lunrStopWordFilter(token) && !nonDefaultLanguages.map(
317806
317953
  (lang) => !!this[lang].stopWordFilter(token)
317807
317954
  ).includes(false) ? token : void 0;
@@ -317825,7 +317972,9 @@ ${inject.head ?? ""}`;
317825
317972
  }
317826
317973
  });
317827
317974
  indexProgress(null);
317828
- yield { "/search-index.json": encoder.encode(JSON.stringify(lunrIndex, null, 4)) };
317975
+ yield {
317976
+ "/search-index.json": encoder.encode(JSON.stringify(lunrIndex, null, 4))
317977
+ };
317829
317978
  }
317830
317979
  async function* generateStaticSiteAssets(versions, currentVersionID, opts) {
317831
317980
  const versionIDsSorted = Array.from(Object.entries(versions)).toSorted(
@@ -322415,22 +322564,8 @@ var buildSite = Command_exports2.make(
322415
322564
  if (prefix && (!prefix.startsWith("/") || prefix.endsWith("/"))) {
322416
322565
  throw new Error("Path prefix must have a leading slash and no trailing slash");
322417
322566
  }
322418
- function maybeDumpCache() {
322419
- if (debug3) {
322420
- try {
322421
- console.warn("Dumping cache to cacheDump.json");
322422
- fs4.writeFileSync(
322423
- "cacheDump.json",
322424
- JSON.stringify(cache3.dump(), null, 2),
322425
- { encoding: "utf-8" }
322426
- );
322427
- } catch (e3) {
322428
- console.error("Cache dump could not be written!", e3);
322429
- }
322430
- }
322431
- }
322432
- process.on("SIGINT", maybeDumpCache);
322433
- render_default(/* @__PURE__ */ import_react129.default.createElement(Processor, { rootTaskName: "build site", onStart: async function({ onProgress }) {
322567
+ let dumping = false;
322568
+ async function generate({ onProgress }) {
322434
322569
  try {
322435
322570
  const generator = generateSite(
322436
322571
  {
@@ -322457,14 +322592,65 @@ var buildSite = Command_exports2.make(
322457
322592
  }
322458
322593
  writeProgress(null);
322459
322594
  onProgress("build site", null);
322595
+ await maybeDumpCache();
322460
322596
  resolve4(void 0);
322461
322597
  } catch (e3) {
322598
+ await maybeDumpCache();
322462
322599
  reject(e3);
322463
322600
  } finally {
322464
- maybeDumpCache();
322465
- process.removeListener("SIGINT", maybeDumpCache);
322466
322601
  }
322467
- } }));
322602
+ }
322603
+ async function maybeDumpCache() {
322604
+ if (dumping || !debug3) {
322605
+ return;
322606
+ }
322607
+ const ac = new AbortController();
322608
+ const filename = "cacheDump.txt";
322609
+ function abortDumpCache() {
322610
+ console.warn("Aborting cache dump");
322611
+ process.removeListener("SIGTERM", abortDumpCache);
322612
+ process.removeListener("SIGINT", abortDumpCache);
322613
+ ac.abort();
322614
+ reject("Aborted");
322615
+ }
322616
+ process.on("SIGTERM", abortDumpCache);
322617
+ process.on("SIGINT", abortDumpCache);
322618
+ return new Promise((resolve5, reject2) => {
322619
+ process.removeListener("SIGINT", maybeDumpCache);
322620
+ dumping = true;
322621
+ try {
322622
+ const stream4 = fs4.createWriteStream(filename, {
322623
+ flags: "w",
322624
+ autoClose: true,
322625
+ emitClose: true,
322626
+ flush: true,
322627
+ encoding: "utf-8",
322628
+ signal: ac.signal
322629
+ });
322630
+ stream4.on("error", function handleCacheDumpStreamError(e3) {
322631
+ console.error("Error writing cache dump", e3);
322632
+ reject2(e3);
322633
+ });
322634
+ stream4.on("close", function handleCloseCacheDumpStream() {
322635
+ console.warn("Cache dump stream close event");
322636
+ resolve5(void 0);
322637
+ stream4.close(function() {
322638
+ console.warn("Exiting");
322639
+ });
322640
+ });
322641
+ stream4.on("ready", function handleOpenCacheDumpStream() {
322642
+ console.warn("Dumping cache due to debug flag");
322643
+ cache3.dump(stream4, ac.signal).then(resolve5, reject2);
322644
+ });
322645
+ } catch (e3) {
322646
+ console.error("Could not start cache dump stream", e3);
322647
+ reject2(e3);
322648
+ } finally {
322649
+ }
322650
+ });
322651
+ }
322652
+ process.on("SIGINT", maybeDumpCache);
322653
+ render_default(/* @__PURE__ */ import_react129.default.createElement(Processor, { rootTaskName: "build site", onStart: generate }));
322468
322654
  }),
322469
322655
  catch: (e3) => {
322470
322656
  console.error(e3);
@@ -156,22 +156,10 @@ const buildSite = Command.
156
156
  if (prefix && (!prefix.startsWith('/') || prefix.endsWith('/'))) {
157
157
  throw new Error("Path prefix must have a leading slash and no trailing slash");
158
158
  }
159
- function maybeDumpCache() {
160
- if (debug) {
161
- try {
162
- console.warn("Dumping cache to cacheDump.json");
163
- fs.writeFileSync(
164
- 'cacheDump.json',
165
- JSON.stringify(cache.dump(), null, 2),
166
- { encoding: 'utf-8' },
167
- );
168
- } catch (e) {
169
- console.error("Cache dump could not be written!", e);
170
- }
171
- }
172
- }
173
- process.on('SIGINT', maybeDumpCache);
174
- render(<Processor rootTaskName="build site" onStart={async function ({ onProgress }) {
159
+
160
+ let dumping = false;
161
+
162
+ async function generate({ onProgress }: { onProgress: TaskProgressCallback }) {
175
163
  try {
176
164
  const generator = generateSite(
177
165
  {
@@ -198,14 +186,80 @@ const buildSite = Command.
198
186
  }
199
187
  writeProgress(null);
200
188
  onProgress('build site', null);
189
+ await maybeDumpCache();
201
190
  resolve(void 0);
202
191
  } catch (e) {
192
+ await maybeDumpCache();
203
193
  reject(e);
204
194
  } finally {
205
- maybeDumpCache();
206
- process.removeListener('SIGINT', maybeDumpCache);
195
+ // Can’t have maybeDumpCache() here, because we want
196
+ // to call it before resolving/rejecting the promise.
207
197
  }
208
- }} />);
198
+ }
199
+
200
+ async function maybeDumpCache() {
201
+ if (dumping || !debug) {
202
+ return;
203
+ }
204
+
205
+ const ac = new AbortController();
206
+ const filename = 'cacheDump.txt';
207
+
208
+ function abortDumpCache() {
209
+ console.warn("Aborting cache dump");
210
+ process.removeListener('SIGTERM', abortDumpCache);
211
+ process.removeListener('SIGINT', abortDumpCache);
212
+ ac.abort();
213
+ reject("Aborted");
214
+ }
215
+
216
+ process.on('SIGTERM', abortDumpCache);
217
+ process.on('SIGINT', abortDumpCache);
218
+
219
+ return new Promise((resolve, reject) => {
220
+ process.removeListener('SIGINT', maybeDumpCache);
221
+ dumping = true;
222
+
223
+ try {
224
+ const stream = fs.createWriteStream(filename, {
225
+ flags: 'w',
226
+ autoClose: true,
227
+ emitClose: true,
228
+ flush: true,
229
+ encoding: 'utf-8',
230
+ signal: ac.signal,
231
+ });
232
+
233
+ stream.on('error', function handleCacheDumpStreamError(e) {
234
+ console.error("Error writing cache dump", e);
235
+ reject(e);
236
+ });
237
+
238
+ stream.on('close', function handleCloseCacheDumpStream() {
239
+ console.warn("Cache dump stream close event");
240
+ resolve(void 0);
241
+
242
+ stream.close(function () {
243
+ console.warn("Exiting");
244
+ });
245
+ });
246
+
247
+ stream.on('ready', function handleOpenCacheDumpStream() {
248
+ console.warn("Dumping cache due to debug flag");
249
+ cache.dump(stream, ac.signal).then(resolve, reject);
250
+ });
251
+
252
+ } catch (e) {
253
+ console.error("Could not start cache dump stream", e);
254
+ reject(e);
255
+ } finally {
256
+ }
257
+ });
258
+ }
259
+
260
+ process.on('SIGINT', maybeDumpCache);
261
+
262
+ render(<Processor rootTaskName="build site" onStart={generate} />);
209
263
  }),
210
264
  catch: (e) => {
211
265
  console.error(e);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@riboseinc/anafero-cli",
3
3
  "type": "module",
4
- "version": "0.0.66",
4
+ "version": "0.0.68",
5
5
  "packageManager": "yarn@4.5.0",
6
6
  "bin": {
7
7
  "build-site": "build-site.mjs"