@pi-r/chrome 0.3.2 → 0.5.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/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2023 Studio Trigger
1
+ Copyright 2023 Wit Studio
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
4
 
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @pi-r/chrome
2
2
 
3
- PEP 402 - Forever Aina
3
+ PEP 402 - Forever Vivy
4
4
 
5
5
  ## LICENSE
6
6
 
package/index.js CHANGED
@@ -12,36 +12,47 @@ const transform_1 = require("@e-mc/document/transform");
12
12
  const Document = require('@e-mc/document');
13
13
  const CACHE_DBRESULT = new Map();
14
14
  const CACHE_LOCALFILE = new Map();
15
+ const CACHE_QUERY = new Map();
16
+ const CACHE_SELECTOR = new Map();
15
17
  const CACHE_DATASET = {};
16
18
  const CACHE_ATRULES = {};
17
19
  let CACHE_TOTAL = 0;
20
+ const [PATTERN_STRING_SOME, PATTERN_STRING_MANY] = (function () {
21
+ const grouping = '(?:\\s|' + dom_1.DomWriter.PATTERN_COMMENT + '|`[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}`)';
22
+ return [grouping + '*', grouping + '+'];
23
+ })();
24
+ const PATTERN_PARENINLINE = '(?:[^()]|\\([^()]+\\(|\\([^)]+\\)|\\)[^()]+\\)|\\)*?)+';
18
25
  const REGEXP_SRCSETSIZE = /~\s*([\d.]+)\s*([wx])/i;
19
26
  const REGEXP_TEMPLATECONDITIONAL = /(\n\s+)?\{\{if\s+((?:[^}]|}(?!}))+?)\}\}(\s*)([\S\s]*?)(?:\s*\{\{else(?:\s+if\s+((?:[^}]|}(?!}))+?))?\}\}(\s*)([\S\s]*?)\s*)?\s*\{\{end\}\}/g;
20
- const REGEXP_TEMPLATECOMPARISON = /\s*\(\s*(?:(eq|ne|lt|le|gt|ge)\s+)?("[^"]+"|'[^']+'|[^\s)]+)(?:\s+("[^"]+"|'[^']+'|[^\s)]+))?\s*\)/g;
21
- const REGEXP_TEMPLATEMATCH = new RegExp(`^(?:(and|or|not)\\s+)?((?:${REGEXP_TEMPLATECOMPARISON.source})+)|(!|not\\s+)?([^\\s][\\S\\s]*)$`);
22
- const REGEXP_IMPORTMODULE = /(?:(?:^|[\n;]+)\s*import\s+(?:("(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+')|.+?from\s+("(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+')(?:[ \t]+assert[ \t]+\{((?:"(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+'|`(?:[^`]|(?<=\\)`)+`|{[^{]+{|{[^}]+}|}[^}]+}|(?![{}])[^"'`])+)\})?)|\bimport\(\s*("(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+')\s*(?:,\s*\{((?:"(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+'|`(?:[^`]|(?<=\\)`)+`|{[^{]+{|{[^}]+}|}[^}]+}|(?![{}])[^"'`])+)\}\s*)?\))/g;
27
+ const REGEXP_TEMPLATECOMPARISON = /\s*\(\s*(?:\b(eq|ne|lt|le|gt|ge)\s+)?("[^"]+"|'[^']+'|[^\s)]+)(?:\s+("[^"]+"|'[^']+'|[^\s)]+))?\s*\)/g;
28
+ const REGEXP_TEMPLATEMATCH = new RegExp(`^(?:\\b(and|or|not)\\s+)?((?:${REGEXP_TEMPLATECOMPARISON.source})+)|(!|not\\s+)?([^\\s][\\S\\s]*)$`);
29
+ const REGEXP_IMPORTMODULE = /(?:(?:^|[\n;]+)\s*import\s+(?:("(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+')|.+?from\s+("(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+')(?:[ \t]+assert[ \t]+\{((?:"(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+'|`(?:[^`]|(?<=\\)`)+`|{[^{]*{|{[^}]*}|}[^}]*}|[^"'`]+)+)\})?)|\bimport\(\s*("(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+')\s*(?:,\s*\{((?:"(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+'|`(?:[^`]|(?<=\\)`)+`|{[^{]*{|{[^}]*}|}[^}]*}|[^"'`]+)+)\}\s*)?\))/g;
23
30
  const REGEXP_BLOCKEXCLUDE = new RegExp(`(\\s*)<!--\\s*exclude\\s*:\\s*(?:start|end)\\s*-->` + dom_1.DomWriter.PATTERN_TRAILINGSPACE, 'gi');
24
- const [PATTERN_STRING_SOME, PATTERN_STRING_MANY] = (function () {
25
- const pattern = '(?:\\s|' + dom_1.DomWriter.PATTERN_COMMENT + '|`[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}`)';
26
- return [pattern + '*', pattern + '+'];
27
- })();
28
31
  const REGEXP_COMMENT = new RegExp(dom_1.DomWriter.PATTERN_COMMENT, 'g');
29
- const REGEXP_CONTENT = new RegExp(`\\bcontent${PATTERN_STRING_SOME}:${PATTERN_STRING_SOME}(?:"[^"]*"|'[^']*')`, 'gi');
32
+ const REGEXP_QUOTEDVALUE = new RegExp(`\\b(?:@import${PATTERN_STRING_MANY}|content${PATTERN_STRING_SOME}:${PATTERN_STRING_SOME})(?:"[^"]*"|'[^']*')`, 'gi');
30
33
  const REGEXP_STYLE = new RegExp(`(<style${dom_1.DomWriter.PATTERN_TAGOPEN}*>)([\\S\\s]*?)(<\\/style\\s*>)`, 'gi');
31
34
  const REGEXP_VARIABLES = new RegExp(`(\\s*)(--[^\\s:]*)${PATTERN_STRING_SOME}:[^;}]*([;}])` + dom_1.DomWriter.PATTERN_TRAILINGSPACE, 'g');
32
35
  const REGEXP_FONTFACE = new RegExp(`(\\s*)@font-face${PATTERN_STRING_SOME}{([^}]+)}` + dom_1.DomWriter.PATTERN_TRAILINGSPACE, 'gi');
33
- const REGEXP_FONTFAMILY = new RegExp(`font-family${PATTERN_STRING_SOME}:([^;}]+)`, 'i');
36
+ const REGEXP_FONTFAMILY = new RegExp(`\\bfont-family${PATTERN_STRING_SOME}:([^;}]+)`, 'i');
34
37
  const REGEXP_KEYFRAMES = new RegExp(`(\\s*)@keyframes${PATTERN_STRING_MANY}([^{]+){`, 'gi');
35
- const REGEXP_NTHCHILD = new RegExp(`\\(${PATTERN_STRING_SOME}([+-])?(?:(\\d*)[nN]|(0))${PATTERN_STRING_SOME}([+-])?${PATTERN_STRING_SOME}(\\d*)${PATTERN_STRING_SOME}\\)`, 'g');
38
+ const REGEXP_PROPERTY = new RegExp(`(\\s*)@property${PATTERN_STRING_MANY}(--[^\\s]+)${PATTERN_STRING_SOME}{`, 'gi');
39
+ const REGEXP_NTHCHILD = new RegExp(`\\(${PATTERN_STRING_SOME}([+-])?(?:(\\d*)[nN]|(0))?${PATTERN_STRING_SOME}([+-])?${PATTERN_STRING_SOME}(\\d*)(?:${PATTERN_STRING_MANY}[oO][fF]${PATTERN_STRING_MANY}(${PATTERN_PARENINLINE})${PATTERN_STRING_SOME}\\)|${PATTERN_STRING_SOME}\\))`, 'g');
36
40
  const REGEXP_VARIABLES_UNSAFE = new RegExp(`(\\s*)(--[^\\s:]*)\\s*:[^;}]*([;}])` + dom_1.DomWriter.PATTERN_TRAILINGSPACE, 'g');
37
41
  const REGEXP_FONTFACE_UNSAFE = new RegExp(`(\\s*)@font-face\\s*{([^}]+)}` + dom_1.DomWriter.PATTERN_TRAILINGSPACE, 'gi');
38
- const REGEXP_FONTFAMILY_UNSAFE = /font-family\s*:([^;}]+)/i;
42
+ const REGEXP_FONTFAMILY_UNSAFE = /\bfont-family\s*:([^;}]+)/i;
39
43
  const REGEXP_KEYFRAMES_UNSAFE = /(\s*)@keyframes\s+([^{]+){/gi;
40
- const REGEXP_NTHCHILD_UNSAFE = /\(\s*([+-])?(?:(\d*)[nN]|(0))\s*([+-])?\s*(\d*)\s*\)/g;
44
+ const REGEXP_PROPERTY_UNSAFE = /(\s*)@property\s+(--[^\s]+)\s*{/gi;
45
+ const REGEXP_NTHCHILD_UNSAFE = new RegExp(`\\(\\s*([+-])?(?:(\\d*)[nN]|(0))?\\s*([+-])?\\s*(\\d*)(?:\\s+[oO][fF]\\s+(${PATTERN_PARENINLINE})\\s*\\)|\\s*\\))`, 'g');
41
46
  const REGEXP_OBJECT_NAME = /([^[.\s]+)((?:\s*\[[^\]]+\]\s*)+)?\s*\.?\s*/g;
42
47
  const REGEXP_OBJECT_SUBSCRIPT = /\[\s*(["'])?(.+?)\1\s*\]/g;
43
48
  const REGEXP_TEMPLATE_LEADING = /\s*\{\{- \s*((?:[^}]|}(?!}))+?)\}\}/g;
44
49
  const REGEXP_TEMPLATE_TRAILING = /\{\{((?:[^}]|}(?!}))+?)\s*? -\}\}\s*/g;
50
+ const REGEXP_URL = /(?:\b[Uu][Rr][Ll]\(|@import\s+(["'])|\b([Hh][Rr][Ee][Ff])\s*=)/g;
51
+ const REGEXP_URL_JS = /\bimport\(/g;
52
+ const REGEXP_URL_SVG = /(?:\b[Uu][Rr][Ll]\(|@import\s+(["'])|\b([Hh][Rr][Ee][Ff])\s*=)/g;
53
+ const REGEXP_IMAGESET = /\b(?:-webkit-)?image-set\(/gi;
54
+ const REGEXP_IMAGESET_URL = /(?:^|[^(])\s*("(\s*[^)][^"]*)"|'(\s*[^)][^"]*)')\s*(?:,|$|[^)][^,]*,?)/g;
55
+ const REGEXP_REPLACECSS = /^@import\s+(?:url\((?:[^)]|(?<=\\)\))+\)|"(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+')(\s*layer(?:\(([^)]*)\)|\b))?(?:\s*supports\(((?:\([^(]+\(|\([^)]+\)|\)[^)]+\)|(?:(?!\))[^(])+|(?:(?!\()[^)])+)+)\))?(.*?);?$/;
45
56
  function removeNamespace(name, source, newline, comments) {
46
57
  if (source.indexOf('-' + name) !== -1) {
47
58
  const [a, b, c, d, e] = CACHE_DATASET[name] || (CACHE_DATASET[name] = [
@@ -106,15 +117,18 @@ function trimQuote(value) {
106
117
  const last = value[value.length - 1];
107
118
  return first === last && (first === '"' || first === "'") ? value.substring(1, value.length - 1).trim() : value;
108
119
  }
109
- function findClosingIndex(source, lastIndex) {
110
- const pattern = /[{}]/g;
120
+ function findClosingIndex(source, lastIndex, char) {
121
+ const pattern = char === '{' ? /[{}]/g : /[()]/g;
111
122
  pattern.lastIndex = lastIndex;
112
123
  let opened = 1, closed = 0, endIndex = -1, trailing = '', match;
113
124
  while (match = pattern.exec(source)) {
114
- if (match[0] === '{') {
125
+ if (match[0] === char) {
115
126
  ++opened;
116
127
  }
117
128
  else if (++closed === opened) {
129
+ if (char === '(') {
130
+ return match.index;
131
+ }
118
132
  endIndex = match.index + 1;
119
133
  let ch;
120
134
  while (isSpace(ch = source[endIndex])) {
@@ -261,22 +275,21 @@ function isTruthy(data, attr, falsey) {
261
275
  }
262
276
  function hasSameOrigin(value, ...other) {
263
277
  for (let url of other) {
264
- if (!url) {
265
- continue;
266
- }
267
- try {
268
- if (typeof value === 'string') {
269
- value = new URL(value);
270
- }
271
- if (typeof url === 'string') {
272
- url = new URL(url);
278
+ if (url) {
279
+ try {
280
+ if (typeof value === 'string') {
281
+ value = new URL(value);
282
+ }
283
+ if (typeof url === 'string') {
284
+ url = new URL(url);
285
+ }
286
+ if (value.origin === url.origin) {
287
+ return true;
288
+ }
273
289
  }
274
- if (value.origin === url.origin) {
275
- return true;
290
+ catch {
276
291
  }
277
292
  }
278
- catch {
279
- }
280
293
  }
281
294
  return false;
282
295
  }
@@ -316,14 +329,10 @@ function getBaseURLs(asset, baseUrl) {
316
329
  }
317
330
  return result;
318
331
  }
319
- function createHash(host, file, bufferMap) {
320
- const hash = file.hash;
321
- if (!hash) {
322
- return;
323
- }
332
+ function createHash(host, file, hash, bufferMap) {
324
333
  const { filename, localUri } = file;
325
334
  try {
326
- const buffer = localUri && bufferMap[localUri] || getBuffer(file);
335
+ const buffer = localUri && bufferMap[localUri] || getBuffer(file, localUri);
327
336
  if (buffer) {
328
337
  const [algorithm, length] = (0, util_1.getHashData)(hash);
329
338
  let value;
@@ -377,8 +386,29 @@ function transformURL(host, parent, type, source, importFile) {
377
386
  const baseHref = getBaseURLs(importFile || parent, this.baseUrl);
378
387
  const isHtml = type === 'html';
379
388
  const isJs = type === 'js';
380
- const pattern = isJs ? /\bimport\(/g : type === 'svg' ? /(?:\b[Uu][Rr][Ll]\(|@import\s+(["'])|\b([Hh][Rr][Ee][Ff])\s*=)/g : /\b[Uu][Rr][Ll]\(|@import\s+(["'])/g;
389
+ const pattern = isJs ? REGEXP_URL_JS : type === 'svg' ? REGEXP_URL_SVG : REGEXP_URL;
390
+ pattern.lastIndex = 0;
391
+ REGEXP_IMAGESET.lastIndex = 0;
381
392
  let length = source.length, modified, match;
393
+ while (match = REGEXP_IMAGESET.exec(source)) {
394
+ const startIndex = match.index + match[0].length;
395
+ const endIndex = findClosingIndex(source, startIndex, '(');
396
+ if (endIndex === -1) {
397
+ continue;
398
+ }
399
+ REGEXP_IMAGESET_URL.lastIndex = 0;
400
+ const original = source.substring(startIndex, endIndex);
401
+ let content = original, url;
402
+ while (url = REGEXP_IMAGESET_URL.exec(original)) {
403
+ const quote = url[2] ? '"' : "'";
404
+ content = content.replace(url[1], `url(${quote + (url[2] || url[3]).trim() + quote})`);
405
+ modified = true;
406
+ }
407
+ if (modified) {
408
+ source = spliceString(source, startIndex, REGEXP_IMAGESET.lastIndex = endIndex, content);
409
+ modified = false;
410
+ }
411
+ }
382
412
  while (match = pattern.exec(source)) {
383
413
  const isText = !!match[1];
384
414
  const isHref = !!match[2];
@@ -735,7 +765,7 @@ function transformJs(host, file, output) {
735
765
  });
736
766
  }
737
767
  else {
738
- this.writeFail(['Unable to create element entry point', path.basename(chunkUri)], (0, types_1.errorMessage)('js', 'Element not found', chunkUri), 4);
768
+ this.writeFail(['Unable to create script entry point', path.basename(chunkUri)], (0, types_1.errorMessage)('js', 'Element not found', chunkUri), 4);
739
769
  }
740
770
  }
741
771
  }
@@ -766,11 +796,16 @@ function replaceCss(file) {
766
796
  }
767
797
  }
768
798
  function replaceHtml(source, { productionRelease, contentMap }, cssMap) {
769
- for (const data of [cssMap, contentMap]) {
799
+ const finalize = (value, data) => {
770
800
  for (const id in data) {
771
- source = source.replace(new RegExp((0, types_1.escapePattern)(id), 'g'), data[id]);
801
+ value = value.replace(new RegExp((0, types_1.escapePattern)(id), 'g'), data[id]);
772
802
  }
803
+ return value;
804
+ };
805
+ if (cssMap) {
806
+ source = finalize(source, cssMap);
773
807
  }
808
+ source = finalize(source, contentMap);
774
809
  return productionRelease ? this.removeServerRoot(source) : source;
775
810
  }
776
811
  function isWatched(file) {
@@ -838,10 +873,6 @@ async function checkData(item, name, result, validate) {
838
873
  }
839
874
  }
840
875
  }
841
- function getBuffer(item) {
842
- let localUri;
843
- return item.sourceUTF8 || item.buffer || ((localUri = item.localUri) && isPath(localUri) ? fs.readFileSync(localUri, item.encoding) : null);
844
- }
845
876
  const getNewlineString = dom_1.DomWriter.getNewlineString.bind(dom_1.DomWriter);
846
877
  const isSpace = dom_1.DomWriter.isSpace.bind(dom_1.DomWriter);
847
878
  const replaceMatch = dom_1.DomWriter.replaceMatch.bind(dom_1.DomWriter);
@@ -852,6 +883,7 @@ const asString = Document.asString.bind(Document);
852
883
  const resolvePath = Document.resolvePath.bind(Document);
853
884
  const toPosix = Document.toPosix.bind(Document);
854
885
  const isDir = Document.isDir.bind(Document);
886
+ const getBuffer = (item, localUri) => item.sourceUTF8 || item.buffer || ((localUri || (localUri = item.localUri)) && isPath(localUri) ? fs.readFileSync(localUri, item.encoding) : null);
855
887
  const hasSourceMap = (metadata, value) => (0, types_1.isObject)(metadata) && metadata.__sourcemap__ === value;
856
888
  const isBundled = (value, main) => typeof value === 'number' && (value > 0 || main && value === 0);
857
889
  const isFont = (value) => value === 'truetype' || value === 'opentype' || value === 'woff' || value === 'woff2';
@@ -880,6 +912,7 @@ class ChromeDocument extends Document {
880
912
  useOriginalHtmlPage: undefined,
881
913
  useUnsafeHtmlReplace: undefined,
882
914
  useUnsafeCssReplace: undefined,
915
+ useSessionCache: undefined,
883
916
  stripCommentsAndCDATA: undefined,
884
917
  normalizeHtmlOutput: undefined,
885
918
  escapeReservedCharacters: undefined,
@@ -902,7 +935,8 @@ class ChromeDocument extends Document {
902
935
  this._elements = null;
903
936
  this._idMap = Object.create(null);
904
937
  this._editing = [];
905
- this._selectorMap = {};
938
+ this._queryMap = new Map();
939
+ this._selectorMap = new Map();
906
940
  }
907
941
  static async purgeMemory(percent = 1, limit = 0, parent) {
908
942
  if (typeof limit === 'boolean') {
@@ -910,14 +944,14 @@ class ChromeDocument extends Document {
910
944
  limit = 0;
911
945
  }
912
946
  let result = 0;
913
- if (limit === 0 || CACHE_TOTAL >= limit) {
947
+ if ((limit === 0 || CACHE_TOTAL >= limit) && percent > 0) {
914
948
  if (percent >= 1) {
915
949
  result += CACHE_DBRESULT.size + CACHE_LOCALFILE.size;
916
950
  CACHE_DBRESULT.clear();
917
951
  CACHE_LOCALFILE.clear();
918
952
  CACHE_TOTAL = 0;
919
953
  }
920
- else if (percent > 0) {
954
+ else {
921
955
  const stored = [];
922
956
  for (const map of [CACHE_DBRESULT, CACHE_LOCALFILE]) {
923
957
  for (const [key, value] of map) {
@@ -932,6 +966,8 @@ class ChromeDocument extends Document {
932
966
  }
933
967
  CACHE_TOTAL = stored.length - result;
934
968
  }
969
+ CACHE_QUERY.clear();
970
+ CACHE_SELECTOR.clear();
935
971
  }
936
972
  return result + (parent && result > 0 ? await super.purgeMemory(typeof parent === 'number' && parent > 0 ? parent : percent, limit, true) : 0);
937
973
  }
@@ -1025,16 +1061,15 @@ class ChromeDocument extends Document {
1025
1061
  const items = new Set((asset.watch.assets || []));
1026
1062
  (function recurse(children) {
1027
1063
  for (const item of children) {
1028
- if (items.has(item)) {
1029
- continue;
1030
- }
1031
- if (isWatched.call(instance, item)) {
1032
- item.flags |= 8;
1033
- }
1034
- items.add(item);
1035
- const next = related.get(item);
1036
- if (next) {
1037
- recurse(next);
1064
+ if (!items.has(item)) {
1065
+ if (isWatched.call(instance, item)) {
1066
+ item.flags |= 8;
1067
+ }
1068
+ items.add(item);
1069
+ const next = related.get(item);
1070
+ if (next) {
1071
+ recurse(next);
1072
+ }
1038
1073
  }
1039
1074
  }
1040
1075
  })(includes);
@@ -1050,20 +1085,18 @@ class ChromeDocument extends Document {
1050
1085
  if (this.canWrite(productionRelease)) {
1051
1086
  const serverRoot = ChromeDocument.INTERNAL_SERVERROOT;
1052
1087
  const srcDir = path.join(this.baseDirectory, serverRoot);
1053
- if (!isDir(srcDir)) {
1054
- return;
1055
- }
1056
- const result = await Document.copyDir(srcDir, productionRelease, this.incremental !== 'staging');
1057
- const failed = result.failed.map(value => this.removeCwd(value));
1058
- for (const value of this.files) {
1059
- if (!value.startsWith(serverRoot)) {
1060
- continue;
1061
- }
1062
- if (!failed.includes(value)) {
1063
- this.delete(value);
1064
- }
1065
- else {
1066
- instance.writeFail(["Unable to move file", instance.moduleName], (0, types_1.errorMessage)('production', path.join(this.baseDirectory, value)), { fatal: true });
1088
+ if (isDir(srcDir)) {
1089
+ const result = await Document.copyDir(srcDir, productionRelease, this.incremental !== 'staging');
1090
+ const failed = result.failed.map(value => this.removeCwd(value));
1091
+ for (const value of this.files) {
1092
+ if (value.startsWith(serverRoot)) {
1093
+ if (!failed.includes(value)) {
1094
+ this.delete(value);
1095
+ }
1096
+ else {
1097
+ instance.writeFail(["Unable to move file", instance.moduleName], (0, types_1.errorMessage)('production', path.join(this.baseDirectory, value)), { fatal: true });
1098
+ }
1099
+ }
1067
1100
  }
1068
1101
  }
1069
1102
  }
@@ -1564,12 +1597,14 @@ class ChromeDocument extends Document {
1564
1597
  }
1565
1598
  for (const placeholder in importMap) {
1566
1599
  const items = importMap[placeholder];
1600
+ let found;
1567
1601
  for (let i = 0, length = items.length; i < length; ++i) {
1568
1602
  const index = code.indexOf(placeholder);
1569
1603
  if (index !== -1) {
1570
1604
  const { uri, original, type, dynamic } = items[i];
1605
+ const hosted = type === 'css';
1571
1606
  let value;
1572
- if (type === 'css') {
1607
+ if (hosted) {
1573
1608
  const asset = this.host?.findAsset(uri);
1574
1609
  if (asset) {
1575
1610
  const [relativeUrl, sameDir] = getSrcURL.call(this, bundleMain || file, asset);
@@ -1581,11 +1616,12 @@ class ChromeDocument extends Document {
1581
1616
  else if (!(dynamic && file.imported !== false)) {
1582
1617
  value = this.findSourceRoot(uri);
1583
1618
  }
1584
- if (!value) {
1619
+ if (!value || !hosted && !Document.isPath(value)) {
1585
1620
  if (i < length - 1) {
1621
+ found || (found = value);
1586
1622
  continue;
1587
1623
  }
1588
- value = original;
1624
+ value = found || original;
1589
1625
  }
1590
1626
  code = spliceString(code, index, index + placeholder.length, value);
1591
1627
  modified = true;
@@ -1600,7 +1636,7 @@ class ChromeDocument extends Document {
1600
1636
  replaceContent(source, statement, mimeType) {
1601
1637
  switch (mimeType) {
1602
1638
  case 'text/css': {
1603
- const match = /^@import\s+(?:url\((?:[^)]|(?<=\\)\))+\)|"(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+')(\s*layer(?:\(([^)]*)\)|\b))?(?:\s*supports\(((?:\([^(]+\(|\([^)]+\)|\)[^)]+\)|(?:(?!\))[^(])+|(?:(?!\()[^)])+)+)\))?(.*?);?$/.exec((typeof statement === 'string' ? statement : statement[0]).trim());
1639
+ const match = REGEXP_REPLACECSS.exec((typeof statement === 'string' ? statement : statement[0]).trim());
1604
1640
  if (match) {
1605
1641
  const layer = match[1];
1606
1642
  const supports = match[3]?.trim();
@@ -1935,12 +1971,12 @@ class ChromeDocument extends Document {
1935
1971
  }
1936
1972
  }
1937
1973
  if (productionRelease) {
1938
- const { imported, inlineUrl: inlineUrl, inlineUrlCloud: inlineUrlCloud } = item;
1974
+ const { inlineUrl, inlineUrlCloud, imported, hash } = item;
1939
1975
  if (inlineUrl || inlineUrlCloud) {
1940
- const filename = createHash(host, item, bufferMap);
1976
+ const filename = hash && createHash(host, item, hash, bufferMap);
1941
1977
  if (filename) {
1942
- for (const hash of this.assets) {
1943
- const url = inlineUrl ? hash.inlineUrlMap?.[inlineUrl] : hash.inlineUrlCloudMap?.[inlineUrlCloud];
1978
+ for (const asset of this.assets) {
1979
+ const url = inlineUrl ? asset.inlineUrlMap?.[inlineUrl] : asset.inlineUrlCloudMap?.[inlineUrlCloud];
1944
1980
  if (url) {
1945
1981
  const search = url.indexOf('?');
1946
1982
  const index = (search !== -1 ? url.substring(0, search) : url).lastIndexOf('/');
@@ -1953,17 +1989,17 @@ class ChromeDocument extends Document {
1953
1989
  result += url.substring(search);
1954
1990
  }
1955
1991
  if (inlineUrl) {
1956
- hash.inlineUrlMap[inlineUrl] = result;
1992
+ asset.inlineUrlMap[inlineUrl] = result;
1957
1993
  }
1958
1994
  else {
1959
- hash.inlineUrlCloudMap[inlineUrlCloud] = result;
1995
+ asset.inlineUrlCloudMap[inlineUrlCloud] = result;
1960
1996
  }
1961
1997
  }
1962
1998
  }
1963
1999
  }
1964
2000
  hashed.add(item);
1965
2001
  }
1966
- else if ((!item.editing || imported) && createHash(host, item, bufferMap)) {
2002
+ else if (hash && (!item.editing || imported) && createHash(host, item, hash, bufferMap)) {
1967
2003
  hashed.add(item);
1968
2004
  }
1969
2005
  }
@@ -2019,7 +2055,7 @@ class ChromeDocument extends Document {
2019
2055
  }
2020
2056
  }
2021
2057
  item.sourceUTF8 = source;
2022
- if (productionRelease && !hashed.has(item) && createHash(host, item, bufferMap)) {
2058
+ if (productionRelease && item.hash && !hashed.has(item) && createHash(host, item, item.hash, bufferMap)) {
2023
2059
  hashed.add(item);
2024
2060
  }
2025
2061
  }
@@ -2436,13 +2472,13 @@ class ChromeDocument extends Document {
2436
2472
  const length = batch.length;
2437
2473
  const current = batch[0];
2438
2474
  const type = current.source;
2439
- let result = new Array(length);
2475
+ let result = new Array(length), errors;
2440
2476
  switch (type) {
2441
2477
  case 'cloud':
2442
2478
  result = await cloud.getDatabaseBatchRows(batch, true, sessionKey).catch(err => {
2443
2479
  this.abort(type);
2444
2480
  if (err instanceof Error) {
2445
- cloud.addLog(this.aborted ? types_1.STATUS_TYPE.ERROR : types_1.STATUS_TYPE.WARN, err);
2481
+ cloud.addLog(this.aborted ? types_1.STATUS_TYPE.ERROR : types_1.STATUS_TYPE.WARN, errors = err);
2446
2482
  }
2447
2483
  return [];
2448
2484
  });
@@ -2608,9 +2644,7 @@ class ChromeDocument extends Document {
2608
2644
  }
2609
2645
  if (!getData) {
2610
2646
  const { settings, encoding, persist = true } = current;
2611
- if (!target) {
2612
- target = settings && this.settings.export?.[settings] || pathname;
2613
- }
2647
+ target || (target = settings && this.settings.export?.[settings] || pathname);
2614
2648
  if (typeof target === 'function') {
2615
2649
  getData = target;
2616
2650
  hint = target.name;
@@ -2697,7 +2731,7 @@ class ChromeDocument extends Document {
2697
2731
  search.schema = loadLocalFile.call(this, current, pathname, cacheData, cmd.encoding);
2698
2732
  }
2699
2733
  catch (err) {
2700
- this.writeFail(['Unable to parse document', path.basename(pathname)], err, { startTime });
2734
+ this.writeFail(['Unable to parse document', path.basename(pathname)], err instanceof Error ? errors = err : err, { startTime });
2701
2735
  search.schema = undefined;
2702
2736
  }
2703
2737
  }
@@ -2783,7 +2817,7 @@ class ChromeDocument extends Document {
2783
2817
  this.abort(type);
2784
2818
  }
2785
2819
  if (err) {
2786
- this.writeFail(["Unable to execute query", message || "Unknown"], err, { type: 65536, startTime });
2820
+ this.writeFail(["Unable to execute query", message || "Unknown"], err instanceof Error ? errors = err : err, { type: 65536, startTime });
2787
2821
  }
2788
2822
  return this.aborted;
2789
2823
  };
@@ -2836,7 +2870,7 @@ class ChromeDocument extends Document {
2836
2870
  if (items.length && !item.transactionFail) {
2837
2871
  const { element, preRender } = item;
2838
2872
  const domElement = new dom_1.HtmlElement(moduleName, element);
2839
- let errors, value = '';
2873
+ let value = '';
2840
2874
  const checkValue = async (name) => {
2841
2875
  const data = await checkData.call(this, item, name, value, row => typeof row === 'string');
2842
2876
  if (data) {
@@ -2925,7 +2959,7 @@ class ChromeDocument extends Document {
2925
2959
  else {
2926
2960
  const pattern = /\$\{\s*([^\s}]+)\s*\}/g;
2927
2961
  while (match = pattern.exec(segment)) {
2928
- segment = replaceMatch(match, segment, match[1] === '__index__' && !(0, types_1.isObject)(row) ? (j + 1).toString() : valueAsString(getObjectValue(row, match[1]), ', '), pattern);
2962
+ segment = replaceMatch(match, segment, match[1] === "__index__" && !(0, types_1.isObject)(row) ? (j + 1).toString() : valueAsString(getObjectValue(row, match[1]), ', '), pattern);
2929
2963
  }
2930
2964
  }
2931
2965
  value += trimTemplate(segment);
@@ -3132,7 +3166,10 @@ class ChromeDocument extends Document {
3132
3166
  }
3133
3167
  else {
3134
3168
  if (!empty && item.type !== 'display' || item.transactionFail) {
3135
- const emptyResponse = (value, service = item.source) => errorDataSource(service + ' -> Empty', value || "Unknown");
3169
+ const emptyResponse = (value, service = item.source) => {
3170
+ value || (value = "Unknown");
3171
+ return errors instanceof Error ? (0, types_1.errorMessage)(service, value, errors.message) : errorDataSource(service + ' -> Empty', value);
3172
+ };
3136
3173
  switch (item.source) {
3137
3174
  case 'cloud': {
3138
3175
  const { service, table, id, query } = item;
@@ -3180,8 +3217,8 @@ class ChromeDocument extends Document {
3180
3217
  if (isIgnored(item, true)) {
3181
3218
  continue;
3182
3219
  }
3183
- if (!hashed.has(item)) {
3184
- createHash(host, item, bufferMap);
3220
+ if (item.hash && !hashed.has(item)) {
3221
+ createHash(host, item, item.hash, bufferMap);
3185
3222
  }
3186
3223
  switch (item.element?.tagName.toLowerCase()) {
3187
3224
  case 'style':
@@ -3222,12 +3259,13 @@ class ChromeDocument extends Document {
3222
3259
  }
3223
3260
  }
3224
3261
  }
3225
- removeUnusedStyles(source, { useUnsafeCssReplace, usedVariables, usedFontFace, usedKeyframes, unusedStyles, unusedMedia, unusedContainer, unusedSupports } = this.config) {
3262
+ removeUnusedStyles(source, { useUnsafeCssReplace, usedVariables, usedFontFace, usedKeyframes, unusedStyles, unusedMedia, unusedContainer, unusedSupports, useSessionCache } = this.config) {
3226
3263
  var _a;
3227
3264
  if (!usedVariables && !usedFontFace && !usedKeyframes && !unusedStyles && !unusedMedia && !unusedContainer && !unusedSupports) {
3228
3265
  return;
3229
3266
  }
3230
- const selectorMap = this._selectorMap;
3267
+ const queryMap = useSessionCache ? CACHE_QUERY : this._queryMap;
3268
+ const selectorMap = useSessionCache ? CACHE_SELECTOR : this._selectorMap;
3231
3269
  const replaceMap = [];
3232
3270
  const getStringSome = () => useUnsafeCssReplace ? '\\s*' : PATTERN_STRING_SOME;
3233
3271
  const getStringMany = () => useUnsafeCssReplace ? '\\s+' : PATTERN_STRING_MANY;
@@ -3235,7 +3273,7 @@ class ChromeDocument extends Document {
3235
3273
  const parseSelector = (value) => {
3236
3274
  const items = [];
3237
3275
  const revised = value.replace(useUnsafeCssReplace ? REGEXP_NTHCHILD_UNSAFE : REGEXP_NTHCHILD, (...capture) => {
3238
- return '`%' + (items.push('\\(' + getStringSome() + (capture[1] === '-' ? '\\x2d' : '\\x2b?') + (capture[2] || '[01]?') + (capture[3] === '0' ? !capture[1] && !capture[2] && !capture[4] && !capture[5] ? '[+-]?0[nN]?' : '0' : '[nN]') + getStringSome() + (capture[5] ? (capture[4] === '-' ? '\\x2d' : '\\x2b') + getStringSome() + capture[5] : `(?:[+-]${getStringSome()}0)?`) + getStringSome() + '\\)') - 1) + '`';
3276
+ return '`%' + (items.push('\\(' + getStringSome() + (capture[1] === '-' ? '\\x2d' : '\\x2b?') + (capture[2] || '[01]?') + (capture[3] === '0' ? !capture[1] && !capture[2] && !capture[4] && !capture[5] ? '[+-]?0[nN]?' : '0' : '[nN]') + getStringSome() + (capture[5] ? (capture[4] === '-' ? '\\x2d' : '\\x2b') + getStringSome() + capture[5] : `(?:[+-]${getStringSome()}0)?`) + (capture[6] ? getStringMany() + '[oO][fF]' + getStringMany() + capture[6].trim() : '') + getStringSome() + '\\)') - 1) + '`';
3239
3277
  });
3240
3278
  let selector = '';
3241
3279
  for (let i = 0, length = revised.length, casing = false, attr = false, quote = false; i < length; i++) {
@@ -3324,17 +3362,17 @@ class ChromeDocument extends Document {
3324
3362
  return `[${capture[1]}]`;
3325
3363
  }
3326
3364
  });
3327
- for (let i = 0; i < items.length; ++i) {
3365
+ for (let i = 0, length = revised.length; i < length; ++i) {
3328
3366
  selector = selector.replace('`%' + i + '`', items[i]);
3329
3367
  }
3330
- return selector.replace(/[ ]+/g, getStringMany()) + getStringSome();
3368
+ return selector.replace(/ +/g, getStringMany()) + getStringSome();
3331
3369
  };
3332
3370
  const replaceUnunsed = (name, items) => {
3333
3371
  for (let value of items) {
3334
3372
  const key = name + '_' + (value = value.trim()) + (useUnsafeCssReplace ? '_1' : '');
3335
- let [pattern] = selectorMap[key] || [], selector = '', rule;
3373
+ let pattern = queryMap.get(key), rule;
3336
3374
  if (!pattern) {
3337
- let flags = 'gi', revised;
3375
+ let flags = 'gi', selector = '', revised;
3338
3376
  if (name === 'container') {
3339
3377
  for (let i = 0, length = value.length, casing = true; i < length; i++) {
3340
3378
  let ch = value[i];
@@ -3370,27 +3408,25 @@ class ChromeDocument extends Document {
3370
3408
  .replace(/\s*(\\[()])\s*/g, (...capture) => getStringSome() + capture[1] + getStringSome())
3371
3409
  .replace(/:\s+/g, getStringSome() + ':' + getStringSome())
3372
3410
  .replace(/\s+([<>/]|<=|>=|\\\*)\s+/g, (...capture) => getStringSome() + capture[1] + getStringSome())
3373
- .replace(/[ ]+/g, getStringMany());
3411
+ .replace(/ +/g, getStringMany());
3374
3412
  if (flags === 'g') {
3375
3413
  selector = selector.replace(/`([a-z][A-Z])`/g, (...capture) => `[${capture[1]}]`);
3376
3414
  }
3377
3415
  }
3378
3416
  pattern = new RegExp('(\\s*)@' + (flags === 'g' ? name.split('').map(ch => `[${ch + ch.toUpperCase()}]`).join('') : name) + getStringMany() + selector + getStringSome() + '{', flags);
3417
+ queryMap.set(key, pattern);
3379
3418
  }
3380
3419
  else {
3381
3420
  pattern.lastIndex = 0;
3382
3421
  }
3383
3422
  while (rule = pattern.exec(current)) {
3384
- const [endIndex, trailing] = findClosingIndex(current, getEndIndex(rule));
3423
+ const [endIndex, trailing] = findClosingIndex(current, getEndIndex(rule), '{');
3385
3424
  if (endIndex !== -1) {
3386
3425
  current = spliceSource(current, rule.index, endIndex, pattern, rule[1], trailing);
3387
3426
  (checkEmpty || (checkEmpty = {}))[name] = true;
3388
3427
  modified = true;
3389
3428
  }
3390
3429
  }
3391
- if (selector) {
3392
- selectorMap[key] = [pattern];
3393
- }
3394
3430
  }
3395
3431
  };
3396
3432
  if (!useUnsafeCssReplace) {
@@ -3407,7 +3443,7 @@ class ChromeDocument extends Document {
3407
3443
  pattern.lastIndex = 0;
3408
3444
  };
3409
3445
  replaceBracket(REGEXP_COMMENT);
3410
- replaceBracket(REGEXP_CONTENT);
3446
+ replaceBracket(REGEXP_QUOTEDVALUE);
3411
3447
  const values = (0, util_1.splitEnclosing)(current, /\burl/gi);
3412
3448
  for (let i = 0, length = values.length; i < length; ++i) {
3413
3449
  const seg = values[i];
@@ -3429,41 +3465,110 @@ class ChromeDocument extends Document {
3429
3465
  replaceUnunsed('container', unusedContainer);
3430
3466
  }
3431
3467
  if (unusedStyles) {
3432
- for (const value of unusedStyles) {
3433
- const key = value + (useUnsafeCssReplace ? '_1' : '');
3434
- let [single, group] = selectorMap[key] || [], selector;
3435
- if (!single || !group) {
3436
- single = new RegExp(`(}|^)(${getStringSome()})(?<!@[^}]*)${selector = parseSelector(value)}\\{([^}]*)\\}` + dom_1.DomWriter.PATTERN_TRAILINGSPACE, 'g');
3437
- group = new RegExp(`((?:}|^)[^{]*?)((?:,${getStringSome()}|(?<!@[^}]*))${selector})(,[^{]*)?\\{`, 'g');
3438
- }
3439
- else {
3440
- single.lastIndex = 0;
3441
- group.lastIndex = 0;
3442
- }
3443
- while ((match = single.exec(current)) && match[3].indexOf('{') === -1) {
3444
- current = spliceSource(current, match.index, getEndIndex(match), single, match[2], match[4], match[1] || '');
3445
- modified = true;
3446
- }
3447
- while (match = group.exec(current)) {
3448
- const opening = match.index + match[0].length;
3449
- const closing = current.indexOf('}', opening);
3450
- if (closing !== -1 && current.substring(opening, closing).indexOf('{') === -1) {
3451
- const middle = match[2][0] === ',';
3452
- const leading = middle ? match[1].trimEnd() : match[1];
3453
- const trailing = match[3];
3454
- const segment = trailing ? (!middle ? (!isSpace(leading[leading.length - 1]) ? ' ' : '') + trailing.substring(1).trimStart() : trailing).trimEnd() : '';
3455
- current = replaceMatch(match, current, leading + segment + ' {');
3456
- group.lastIndex = match.index;
3457
- modified = true;
3468
+ current = (function recurse(target, child) {
3469
+ let output = '', index = 0, pendingStart = 0, pendingEnd = 0, found = -1;
3470
+ while ((found = target.indexOf('{', index)) !== -1) {
3471
+ ++found;
3472
+ const closing = findClosingIndex(target, found, '{')[0];
3473
+ if (closing === -1) {
3474
+ break;
3475
+ }
3476
+ let header = target.substring(index, found), invalid = 0, content;
3477
+ for (const value of unusedStyles) {
3478
+ const key = value + (child ? '_1' : '') + (useUnsafeCssReplace ? '_2' : '');
3479
+ const pattern = selectorMap.get(key);
3480
+ let single, group;
3481
+ if (!pattern) {
3482
+ const selector = parseSelector(value) + (child ? `(?:${getStringSome()}&${getStringSome()})*` : '');
3483
+ single = new RegExp(`(^|;)(${getStringSome()})(?<!${child ? '&|' : ''}@[^};]*)${selector}\\{$`);
3484
+ group = new RegExp(`((?:^|;)[^{]*?${getStringSome()}(,${getStringSome()}|(?<!@[^};]*)))(${(child ? '(?:&\\s+|(?<!&))' : '') + selector})(,[^{]*)?\\{$`, 'g');
3485
+ selectorMap.set(key, [single, group]);
3486
+ }
3487
+ else {
3488
+ [single, group] = pattern;
3489
+ }
3490
+ if (match = single.exec(header)) {
3491
+ content = match[1] === ';' ? header.substring(0, match.index + 1) + match[2].replace(/[^\n]+$/, '') : undefined;
3492
+ invalid = 1;
3493
+ break;
3494
+ }
3495
+ let leading = -1, first = true;
3496
+ while (match = group.exec(header)) {
3497
+ const start = match.index + match[1].length;
3498
+ if (!child && first) {
3499
+ if (match[1].trimEnd().endsWith(';')) {
3500
+ leading = start;
3501
+ }
3502
+ first = false;
3503
+ }
3504
+ const sibling = match[2][0] === ',';
3505
+ const trailing = match[4];
3506
+ const offset = trailing && !sibling ? /^,\s*/.exec(trailing)[0].length : 1;
3507
+ header = header.substring(0, start - (sibling ? match[2].length : 0)) + header.substring(start + match[3].length + (trailing ? sibling ? 0 : offset : /\s$/.test(match[3]) ? -1 : 0));
3508
+ group.lastIndex = match.index;
3509
+ invalid = 2;
3510
+ }
3511
+ if (invalid) {
3512
+ group.lastIndex = 0;
3513
+ const empty = /(.)\s*{$/.exec(header);
3514
+ if (empty) {
3515
+ if (header.trim() === '{') {
3516
+ content = undefined;
3517
+ invalid = 1;
3518
+ break;
3519
+ }
3520
+ else if (leading !== -1 && empty[1] === ';') {
3521
+ content = target.substring(index, found).substring(0, leading).replace(/[^\n;]+$/, '');
3522
+ invalid = 1;
3523
+ break;
3524
+ }
3525
+ }
3526
+ }
3527
+ }
3528
+ if (invalid === 0 || invalid === 2) {
3529
+ const trailing = target.substring(found, closing);
3530
+ if (content = recurse(trailing, true)) {
3531
+ content = header + content;
3532
+ }
3533
+ else if (invalid === 2) {
3534
+ content = header + trailing;
3535
+ }
3458
3536
  }
3537
+ if (content) {
3538
+ if (pendingEnd) {
3539
+ output = target.substring(pendingStart, pendingEnd) + content;
3540
+ pendingEnd = 0;
3541
+ }
3542
+ else {
3543
+ output += content;
3544
+ }
3545
+ }
3546
+ else if (!invalid) {
3547
+ if (output) {
3548
+ output += target.substring(index, closing);
3549
+ }
3550
+ else {
3551
+ pendingEnd = closing;
3552
+ }
3553
+ }
3554
+ else if (pendingEnd) {
3555
+ output = target.substring(pendingStart, pendingEnd);
3556
+ pendingEnd = 0;
3557
+ }
3558
+ else {
3559
+ pendingStart = closing;
3560
+ }
3561
+ index = closing;
3459
3562
  }
3460
- if (selector) {
3461
- selectorMap[key] = [single, group];
3563
+ if (output) {
3564
+ modified = true;
3565
+ return output + target.substring(index);
3462
3566
  }
3463
- }
3567
+ return !child ? target : '';
3568
+ })(current, false);
3464
3569
  }
3465
3570
  if (usedVariables) {
3466
- const pattern = useUnsafeCssReplace ? REGEXP_VARIABLES_UNSAFE : REGEXP_VARIABLES;
3571
+ let pattern = useUnsafeCssReplace ? REGEXP_VARIABLES_UNSAFE : REGEXP_VARIABLES;
3467
3572
  while (match = pattern.exec(current)) {
3468
3573
  if (!usedVariables.includes(match[2])) {
3469
3574
  current = replaceMatch(match, current, match[3] === ';' ? getNewlineString(match[1], match[4]) : '', pattern);
@@ -3471,24 +3576,35 @@ class ChromeDocument extends Document {
3471
3576
  }
3472
3577
  }
3473
3578
  pattern.lastIndex = 0;
3579
+ pattern = useUnsafeCssReplace ? REGEXP_PROPERTY_UNSAFE : REGEXP_PROPERTY;
3580
+ while (match = pattern.exec(current)) {
3581
+ if (!usedVariables.includes(match[2])) {
3582
+ const [endIndex, trailing] = findClosingIndex(current, getEndIndex(match), '{');
3583
+ if (endIndex !== -1) {
3584
+ current = spliceSource(current, match.index, endIndex, pattern, match[1], trailing);
3585
+ modified = true;
3586
+ }
3587
+ }
3588
+ }
3589
+ pattern.lastIndex = 0;
3474
3590
  }
3475
3591
  if (usedFontFace) {
3476
- const fontFace = useUnsafeCssReplace ? REGEXP_FONTFACE_UNSAFE : REGEXP_FONTFACE;
3592
+ const pattern = useUnsafeCssReplace ? REGEXP_FONTFACE_UNSAFE : REGEXP_FONTFACE;
3477
3593
  const fontFamily = useUnsafeCssReplace ? REGEXP_FONTFAMILY_UNSAFE : REGEXP_FONTFAMILY;
3478
- while (match = fontFace.exec(current)) {
3594
+ while (match = pattern.exec(current)) {
3479
3595
  const font = fontFamily.exec(match[0]);
3480
3596
  if (font && !usedFontFace.includes(font[1].trim().replace(/^(["'])([\S\s]+)\1$/, (...content) => content[2]))) {
3481
- current = spliceSource(current, match.index, getEndIndex(match), fontFace, match[1], match[3]);
3597
+ current = spliceSource(current, match.index, getEndIndex(match), pattern, match[1], match[3]);
3482
3598
  modified = true;
3483
3599
  }
3484
3600
  }
3485
- fontFace.lastIndex = 0;
3601
+ pattern.lastIndex = 0;
3486
3602
  }
3487
3603
  if (usedKeyframes) {
3488
3604
  const pattern = useUnsafeCssReplace ? REGEXP_KEYFRAMES_UNSAFE : REGEXP_KEYFRAMES;
3489
3605
  while (match = pattern.exec(current)) {
3490
3606
  if (!usedKeyframes.includes(match[2].trim())) {
3491
- const [endIndex, trailing] = findClosingIndex(current, getEndIndex(match));
3607
+ const [endIndex, trailing] = findClosingIndex(current, getEndIndex(match), '{');
3492
3608
  if (endIndex !== -1) {
3493
3609
  current = spliceSource(current, match.index, endIndex, pattern, match[1], trailing);
3494
3610
  modified = true;
@@ -3543,7 +3659,9 @@ class ChromeDocument extends Document {
3543
3659
  return this._editing;
3544
3660
  }
3545
3661
  set dataSource(value) {
3546
- this._dataSource = value;
3662
+ if (Array.isArray(value)) {
3663
+ this._dataSource = value;
3664
+ }
3547
3665
  }
3548
3666
  get dataSource() {
3549
3667
  const result = this._dataSource;
@@ -3566,8 +3684,8 @@ class ChromeDocument extends Document {
3566
3684
  return (_a = this.module).settings || (_a.settings = {});
3567
3685
  }
3568
3686
  }
3569
- ChromeDocument.INTERNAL_ASSIGNUUID = '__assign__';
3570
- ChromeDocument.INTERNAL_SERVERROOT = '__serverroot__';
3687
+ ChromeDocument.INTERNAL_ASSIGNUUID = "__assign__";
3688
+ ChromeDocument.INTERNAL_SERVERROOT = "__serverroot__";
3571
3689
  exports.default = ChromeDocument;
3572
3690
 
3573
3691
  if (exports.default) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-r/chrome",
3
- "version": "0.3.2",
3
+ "version": "0.5.2",
4
4
  "description": "Chrome document constructor for E-mc.",
5
5
  "main": "index.js",
6
6
  "publishConfig": {
@@ -20,9 +20,9 @@
20
20
  "license": "MIT",
21
21
  "homepage": "https://github.com/anpham6/pi-r#readme",
22
22
  "dependencies": {
23
- "@e-mc/cloud": "^0.6.1",
24
- "@e-mc/core": "^0.6.1",
25
- "@e-mc/document": "^0.6.1",
26
- "@e-mc/types": "^0.6.1"
23
+ "@e-mc/cloud": "^0.7.2",
24
+ "@e-mc/core": "^0.7.2",
25
+ "@e-mc/document": "^0.7.2",
26
+ "@e-mc/types": "^0.7.2"
27
27
  }
28
28
  }
package/types/index.d.ts CHANGED
@@ -10,6 +10,13 @@ import type { IDomWriter, IXmlElement } from '@e-mc/document/parse/types';
10
10
 
11
11
  import type { ChromeAsset, CssRuleData, DataSource, DocumentOutput } from './squared';
12
12
 
13
+ export const enum PROPERTIES {
14
+ INDEX = '__index__',
15
+ FROM_HTML = '__fromhtml__',
16
+ ASSIGN = '__assign__',
17
+ SERVERROOT = '__serverroot__'
18
+ }
19
+
13
20
  interface DocumentDirectory extends IDocumentDirectory {
14
21
  template?: string;
15
22
  data?: string;
@@ -116,4 +123,4 @@ export interface ChromeDocumentConstructor<T extends IFileManager<U>, U extends
116
123
  INTERNAL_SERVERROOT: string;
117
124
  readonly prototype: IChromeDocument<T, U>;
118
125
  new(module?: DocumentModule, ...args: unknown[]): IChromeDocument<T, U>;
119
- }
126
+ }
@@ -29,6 +29,7 @@ export interface DocumentOutput {
29
29
  productionIncremental?: boolean;
30
30
  useOriginalHtmlPage?: boolean | string;
31
31
  useUnsafeReplace?: ArrayOf<"html" | "css"> | boolean;
32
+ useSessionCache?: boolean;
32
33
  stripCommentsAndCDATA?: boolean | string;
33
34
  normalizeHtmlOutput?: boolean | string;
34
35
  escapeReservedCharacters?: boolean;