@pi-r/chrome 0.6.6 → 0.7.0

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/README.md CHANGED
@@ -1,10 +1,7 @@
1
- # @pi-r/chrome
1
+ ### @pi-r/chrome
2
2
 
3
- ## Documentation
3
+ https://e-mc.readthedocs.io/en/latest/document
4
4
 
5
- - [E-mc](https://e-mc.readthedocs.io/en/latest/document/index.html)
6
- - [squared](https://squared.readthedocs.io)
7
-
8
- ## LICENSE
5
+ ### LICENSE
9
6
 
10
7
  MIT
package/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import type { IFileManager } from '@e-mc/types/lib';
2
-
3
- import type { ChromeDocumentConstructor, DocumentAsset } from './types';
4
-
5
- declare const Chrome: ChromeDocumentConstructor<IFileManager<DocumentAsset>>;
6
-
1
+ import type { IFileManager } from '@e-mc/types/lib';
2
+
3
+ import type { ChromeDocumentConstructor, DocumentAsset } from './types';
4
+
5
+ declare const Chrome: ChromeDocumentConstructor<IFileManager<DocumentAsset>>;
6
+
7
7
  export = Chrome;
package/index.js CHANGED
@@ -58,13 +58,13 @@ const REGEXP_IMAGESET = /\b(?:-webkit-)?image-set\(/gi;
58
58
  const REGEXP_IMAGESET_URL = /(?:^|[^(])\s*("(\s*[^)][^"]*)"|'(\s*[^)][^"]*)')\s*(?:,|$|[^)][^,]*,?)/g;
59
59
  function removeNamespace(name, source, newline, comments) {
60
60
  if (source.includes('-' + name)) {
61
- const [a, b, c, d, e] = CACHE_DATASET[name] || (CACHE_DATASET[name] = [
61
+ const [a, b, c, d, e] = CACHE_DATASET[name] ||= [
62
62
  new RegExp(`(\\s*)<(script|style)(${dom_1.DomWriter.PATTERN_TAGOPEN}+)>[\\S\\s]*?<\\/\\2\\s*>` + dom_1.DomWriter.PATTERN_TRAILINGSPACE, 'gi'),
63
63
  new RegExp(`(\\s*)<link(${dom_1.DomWriter.PATTERN_TAGOPEN}+)>` + dom_1.DomWriter.PATTERN_TRAILINGSPACE, 'gi'),
64
64
  new RegExp(`\\s+data-${name}-[a-z-]+\\s*` + dom_1.DomWriter.PATTERN_ATTRVALUE, 'g'),
65
65
  new RegExp(`data-${name}-file\\s*=\\s*(["'])?exclude\\1`),
66
66
  new RegExp(`data-${name}-template\\s*` + dom_1.DomWriter.PATTERN_ATTRVALUE)
67
- ]);
67
+ ];
68
68
  source = source
69
69
  .replace(a, (...capture) => d.test(capture[3]) || e.test(capture[3]) ? getNewlineString(capture[1], capture[7], newline) : capture[0])
70
70
  .replace(b, (...capture) => d.test(capture[2]) ? getNewlineString(capture[1], capture[6], newline) : capture[0])
@@ -477,13 +477,13 @@ function transformURL(host, parent, type, source, importFile) {
477
477
  if (asset) {
478
478
  if (!asset.inlineBase64) {
479
479
  if (host.Cloud?.getStorage('upload', asset.cloudStorage)) {
480
- const inlineUrlCloud = asset.inlineUrlCloud || (asset.inlineUrlCloud = (0, types_1.generateUUID)());
481
- (parent.inlineUrlCloudMap || (parent.inlineUrlCloudMap = {}))[inlineUrlCloud] = value;
480
+ const inlineUrlCloud = asset.inlineUrlCloud ||= (0, types_1.generateUUID)();
481
+ (parent.inlineUrlCloudMap ||= {})[inlineUrlCloud] = value;
482
482
  value = inlineUrlCloud;
483
483
  }
484
484
  else if (asset.hash && this.productionRelease) {
485
- const inlineUrl = asset.inlineUrl || (asset.inlineUrl = (0, types_1.generateUUID)());
486
- (parent.inlineUrlMap || (parent.inlineUrlMap = {}))[inlineUrl] = value;
485
+ const inlineUrl = asset.inlineUrl ||= (0, types_1.generateUUID)();
486
+ (parent.inlineUrlMap ||= {})[inlineUrl] = value;
487
487
  value = inlineUrl;
488
488
  }
489
489
  }
@@ -629,7 +629,7 @@ function transformURL(host, parent, type, source, importFile) {
629
629
  }
630
630
  }
631
631
  else if (!asset.invalid) {
632
- fullUrl = asset.inlineBase64 || (asset.inlineBase64 = (0, types_1.generateUUID)());
632
+ fullUrl = asset.inlineBase64 ||= (0, types_1.generateUUID)();
633
633
  }
634
634
  if (url !== fullUrl) {
635
635
  setOutputURL(fullUrl, asset);
@@ -666,7 +666,7 @@ function setLocationUUID(data, file, ext) {
666
666
  const assignUUID = ChromeDocument.INTERNAL_ASSIGNUUID;
667
667
  let index, modified;
668
668
  if (filename) {
669
- ext || (ext = path.extname(filename).substring(1));
669
+ ext ||= path.extname(filename).substring(1);
670
670
  if ((index = filename.indexOf(assignUUID)) !== -1) {
671
671
  data.filename = spliceString(filename, index, index + assignUUID.length, getFormatUUID.call(this, 'filename', ext));
672
672
  if (file) {
@@ -738,7 +738,7 @@ function transformJs(host, file, output) {
738
738
  for (const item of elements) {
739
739
  const append = item.append;
740
740
  if (append && !append.prepend && dom_1.DomWriter.isEqual(item, element, host.moduleName, true)) {
741
- (appending || (appending = [])).push(append);
741
+ (appending ||= []).push(append);
742
742
  }
743
743
  }
744
744
  }
@@ -759,7 +759,7 @@ function transformJs(host, file, output) {
759
759
  if (element) {
760
760
  const attributes = { ...file.attributes, src: joinPath(relativeDir, chunkName) };
761
761
  if (file.imports && file.imported !== false) {
762
- attributes.type || (attributes.type = 'module');
762
+ attributes.type ||= 'module';
763
763
  }
764
764
  elements.push({
765
765
  ...element,
@@ -829,7 +829,7 @@ function loadLocalFile(item, pathname, cacheData, encoding, out) {
829
829
  if (ext === 'cjs') {
830
830
  return require(pathname);
831
831
  }
832
- content || (content = fs.readFileSync(pathname, encoding));
832
+ content ||= fs.readFileSync(pathname, encoding);
833
833
  const result = this.tryParse(content, ext);
834
834
  if (result !== undefined && result !== null) {
835
835
  setCacheData.call(this, item, result, pathname, cacheData, true);
@@ -886,7 +886,7 @@ const asString = Document.asString.bind(Document);
886
886
  const resolvePath = Document.resolvePath.bind(Document);
887
887
  const toPosix = Document.toPosix.bind(Document);
888
888
  const isDir = Document.isDir.bind(Document);
889
- const getBuffer = (item, localUri) => item.sourceUTF8 || item.buffer || ((localUri || (localUri = item.localUri)) && isPath(localUri) ? fs.readFileSync(localUri, item.encoding) : null);
889
+ const getBuffer = (item, localUri) => item.sourceUTF8 || item.buffer || ((localUri ||= item.localUri) && isPath(localUri) ? fs.readFileSync(localUri, item.encoding) : null);
890
890
  const hasSourceMap = (metadata, value) => (0, types_1.isObject)(metadata) && metadata.__sourcemap__ === value;
891
891
  const isBundled = (value, main) => typeof value === 'number' && (value > 0 || main && value === 0);
892
892
  const isFont = (value) => value === 'truetype' || value === 'opentype' || value === 'woff' || value === 'woff2';
@@ -901,46 +901,8 @@ const getRelativeURL = (file) => joinPath(file.moveTo, file.pathname, file.inlin
901
901
  const errorHtml = ({ tagName, tagIndex = -1 }) => (0, types_1.errorMessage)('html', 'Location did not resolve', tagName.toLowerCase() + (tagIndex >= 0 ? ': ' + tagIndex : ''));
902
902
  const errorDataSource = (value, hint) => (0, types_1.errorMessage)('data-source', value, hint);
903
903
  class ChromeDocument extends Document {
904
- constructor() {
905
- super(...arguments);
906
- this.config = {
907
- usedVariables: undefined,
908
- usedFontFace: undefined,
909
- usedKeyframes: undefined,
910
- unusedStyles: undefined,
911
- unusedMedia: undefined,
912
- unusedContainer: undefined,
913
- unusedSupports: undefined,
914
- unusedAtRules: undefined,
915
- useOriginalHtmlPage: undefined,
916
- useUnsafeHtmlReplace: undefined,
917
- useUnsafeCssReplace: undefined,
918
- useSessionCache: undefined,
919
- stripCommentsAndCDATA: undefined,
920
- normalizeHtmlOutput: undefined,
921
- escapeReservedCharacters: undefined,
922
- ignoreServerCodeBlocks: undefined
923
- };
924
- this.htmlFile = null;
925
- this.cssFiles = [];
926
- this.jsFiles = [];
927
- this.svgFiles = [];
928
- this.baseDirectory = '';
929
- this.baseUrl = '';
930
- this.productionRelease = false;
931
- this.productionIncremental = false;
932
- this.templateMap = {};
933
- this.userAgentData = {};
934
- this.related = new Map();
935
- this.replaced = [];
936
- this._moduleName = 'chrome';
937
- this._threadable = true;
938
- this._elements = null;
939
- this._idMap = Object.create(null);
940
- this._editing = [];
941
- this._queryMap = new Map();
942
- this._selectorMap = new Map();
943
- }
904
+ static INTERNAL_ASSIGNUUID = "__assign__";
905
+ static INTERNAL_SERVERROOT = "__serverroot__";
944
906
  static async purgeMemory(percent = 1, limit = 0, parent) {
945
907
  if (typeof limit === 'boolean') {
946
908
  parent = limit;
@@ -1081,35 +1043,34 @@ class ChromeDocument extends Document {
1081
1043
  }
1082
1044
  }
1083
1045
  let productionRelease = instance.productionRelease;
1084
- if (!(0, types_1.isString)(productionRelease)) {
1085
- return;
1086
- }
1087
- if (path.isAbsolute(productionRelease = path.normalize(productionRelease)) && isDir(productionRelease)) {
1088
- if (this.canWrite(productionRelease)) {
1089
- const serverRoot = ChromeDocument.INTERNAL_SERVERROOT;
1090
- const srcDir = path.join(this.baseDirectory, serverRoot);
1091
- if (isDir(srcDir)) {
1092
- const result = await Document.copyDir(srcDir, productionRelease, this.incremental !== 'staging');
1093
- const failed = result.failed.map(value => this.removeCwd(value));
1094
- for (const value of this.files) {
1095
- if (value.startsWith(serverRoot)) {
1096
- if (!failed.includes(value)) {
1097
- this.delete(value);
1098
- }
1099
- else {
1100
- instance.writeFail(["Unable to move file", instance.moduleName], (0, types_1.errorMessage)('production', path.join(this.baseDirectory, value)), { fatal: true });
1046
+ if ((0, types_1.isString)(productionRelease)) {
1047
+ if (path.isAbsolute(productionRelease = path.normalize(productionRelease)) && isDir(productionRelease)) {
1048
+ if (this.canWrite(productionRelease)) {
1049
+ const serverRoot = ChromeDocument.INTERNAL_SERVERROOT;
1050
+ const srcDir = path.join(this.baseDirectory, serverRoot);
1051
+ if (isDir(srcDir)) {
1052
+ const result = await Document.copyDir(srcDir, productionRelease, this.incremental !== 'staging');
1053
+ const failed = result.failed.map(value => this.removeCwd(value));
1054
+ for (const value of this.files) {
1055
+ if (value.startsWith(serverRoot)) {
1056
+ if (!failed.includes(value)) {
1057
+ this.delete(value);
1058
+ }
1059
+ else {
1060
+ instance.writeFail(["Unable to move file", instance.moduleName], (0, types_1.errorMessage)('production', path.join(this.baseDirectory, value)), { fatal: true });
1061
+ }
1101
1062
  }
1102
1063
  }
1103
1064
  }
1104
1065
  }
1066
+ else {
1067
+ instance.writeFail(["Unable to write directory", instance.moduleName], (0, types_1.errorMessage)('production', "Unsupported access", productionRelease));
1068
+ }
1105
1069
  }
1106
1070
  else {
1107
- instance.writeFail(["Unable to write directory", instance.moduleName], (0, types_1.errorMessage)('production', 'Access denied', productionRelease));
1071
+ instance.writeFail(["Unable to read directory", instance.moduleName], (0, types_1.errorMessage)('production', 'Invalid directory', productionRelease), 32);
1108
1072
  }
1109
1073
  }
1110
- else {
1111
- instance.writeFail(["Unable to read directory", instance.moduleName], (0, types_1.errorMessage)('production', 'Invalid directory', productionRelease), 32);
1112
- }
1113
1074
  }
1114
1075
  static sanitizeAssets(assets, exclusions = []) {
1115
1076
  assets.forEach(item => {
@@ -1134,6 +1095,50 @@ class ChromeDocument extends Document {
1134
1095
  }
1135
1096
  });
1136
1097
  }
1098
+ config = {
1099
+ usedVariables: undefined,
1100
+ usedFontFace: undefined,
1101
+ usedKeyframes: undefined,
1102
+ unusedStyles: undefined,
1103
+ unusedMedia: undefined,
1104
+ unusedSupports: undefined,
1105
+ unusedContainer: undefined,
1106
+ unusedScope: undefined,
1107
+ unusedAtRules: undefined,
1108
+ useOriginalHtmlPage: undefined,
1109
+ useUnsafeHtmlReplace: undefined,
1110
+ useUnsafeCssReplace: undefined,
1111
+ useSessionCache: undefined,
1112
+ stripCommentsAndCDATA: undefined,
1113
+ normalizeHtmlOutput: undefined,
1114
+ escapeReservedCharacters: undefined,
1115
+ ignoreServerCodeBlocks: undefined
1116
+ };
1117
+ htmlFile = null;
1118
+ cssFiles = [];
1119
+ jsFiles = [];
1120
+ svgFiles = [];
1121
+ baseDirectory = '';
1122
+ baseUrl = '';
1123
+ productionRelease = false;
1124
+ productionIncremental = false;
1125
+ templateMap = {};
1126
+ userAgentData = {};
1127
+ related = new Map();
1128
+ replaced = [];
1129
+ formatMap;
1130
+ _moduleName = 'chrome';
1131
+ _threadable = true;
1132
+ _dataSource;
1133
+ _mimeMap;
1134
+ _elements = null;
1135
+ _cloudUrlMap;
1136
+ _cloudUploaded;
1137
+ _cloudEndpoint;
1138
+ _idMap = Object.create(null);
1139
+ _editing = [];
1140
+ _queryMap = new Map();
1141
+ _selectorMap = new Map();
1137
1142
  init(assets, config) {
1138
1143
  assets.sort((a, b) => {
1139
1144
  if (!(0, types_1.isEmpty)(a.bundleId) && a.bundleId === b.bundleId) {
@@ -1163,19 +1168,15 @@ class ChromeDocument extends Document {
1163
1168
  else {
1164
1169
  item.editing = false;
1165
1170
  }
1166
- item.mimeType = 'text/html';
1167
1171
  break;
1168
1172
  case 'text/css':
1169
1173
  this.cssFiles.push(item);
1170
1174
  this._editing.push(item);
1171
- item.editing = true;
1172
- item.mimeType = 'text/css';
1173
1175
  break;
1174
1176
  case 'text/javascript':
1175
1177
  case 'application/javascript':
1176
1178
  this.jsFiles.push(item);
1177
1179
  this._editing.push(item);
1178
- item.editing = true;
1179
1180
  item.mimeType = 'application/javascript';
1180
1181
  break;
1181
1182
  }
@@ -1426,27 +1427,30 @@ class ChromeDocument extends Document {
1426
1427
  const instance = host.loadModule('compress');
1427
1428
  const buffer = host.getBuffer(file);
1428
1429
  if (instance && buffer) {
1429
- await instance.tryFile(buffer, { format: to, filename: file.filename, etag: file.etag }, (err, result, ext) => {
1430
- if (err) {
1431
- setFormat();
1432
- this.writeFail("Unable to compress file", err, 8);
1433
- }
1434
- else if (result) {
1430
+ const options = { format: to, filename: file.filename, etag: file.etag };
1431
+ await instance.tryFile(buffer, options)
1432
+ .then(result => {
1433
+ if (result) {
1434
+ let ext = options.outExt;
1435
1435
  if (ext) {
1436
1436
  setFormat(ext.startsWith('woff') ? ext : ext === 'otf' ? 'opentype' : 'truetype');
1437
1437
  }
1438
- const output = (0, types_1.renameExt)(localUri, ext || (ext = to));
1438
+ const output = (0, types_1.renameExt)(localUri, ext ||= to);
1439
1439
  file.mimeType = 'font/' + ext;
1440
- fs.writeFile(output, result, error => {
1441
- if (!error) {
1442
- file.buffer = result;
1440
+ fs.writeFile(output, result, err => {
1441
+ if (!err) {
1442
+ file.buffer = Buffer.from(result);
1443
1443
  host.replace(file, output);
1444
1444
  }
1445
1445
  else {
1446
- this.writeFail("Unable to write file", error, 32);
1446
+ this.writeFail("Unable to write file", err, 32);
1447
1447
  }
1448
1448
  });
1449
1449
  }
1450
+ })
1451
+ .catch((err) => {
1452
+ setFormat();
1453
+ this.writeFail("Unable to compress file", err, 8);
1450
1454
  });
1451
1455
  }
1452
1456
  break;
@@ -1581,7 +1585,6 @@ class ChromeDocument extends Document {
1581
1585
  return (trailing !== undefined ? [source, trailing] : source);
1582
1586
  }
1583
1587
  resolveImports(file, code, baseFile) {
1584
- var _a;
1585
1588
  if (!Array.isArray(file.imports)) {
1586
1589
  return;
1587
1590
  }
@@ -1597,7 +1600,7 @@ class ChromeDocument extends Document {
1597
1600
  }
1598
1601
  const importMap = {};
1599
1602
  for (const item of file.imports) {
1600
- (importMap[_a = item.placeholder] || (importMap[_a] = [])).push(item);
1603
+ (importMap[item.placeholder] ||= []).push(item);
1601
1604
  }
1602
1605
  for (const placeholder in importMap) {
1603
1606
  const items = importMap[placeholder];
@@ -1622,7 +1625,7 @@ class ChromeDocument extends Document {
1622
1625
  }
1623
1626
  if (!value || !hosted && !Document.isPath(value)) {
1624
1627
  if (i < length - 1) {
1625
- found || (found = value);
1628
+ found ||= value;
1626
1629
  continue;
1627
1630
  }
1628
1631
  value = found || original;
@@ -1684,7 +1687,7 @@ class ChromeDocument extends Document {
1684
1687
  if (output && command && file.element?.outerXml) {
1685
1688
  const match = REGEXP_SRCSETSIZE.exec(command);
1686
1689
  if (match) {
1687
- (file.srcSet || (file.srcSet = [])).push(toPosix(data.baseDirectory ? output.substring(data.baseDirectory.length + 1) : output), match[1] + match[2].toLowerCase());
1690
+ (file.srcSet ||= []).push(toPosix(data.baseDirectory ? output.substring(data.baseDirectory.length + 1) : output), match[1] + match[2].toLowerCase());
1688
1691
  file.modified = true;
1689
1692
  return true;
1690
1693
  }
@@ -1738,6 +1741,7 @@ class ChromeDocument extends Document {
1738
1741
  }
1739
1742
  const { host, instance, localStorage } = state;
1740
1743
  const htmlFile = this.htmlFile;
1744
+ const preferBuffer = process.env.EMC_CLOUD_UPLOAD_BUFFER === 'true';
1741
1745
  const checkDocument = (item) => {
1742
1746
  if (item.inlineUrlCloudMap) {
1743
1747
  const source = host.getUTF8String(item);
@@ -1751,7 +1755,7 @@ class ChromeDocument extends Document {
1751
1755
  }
1752
1756
  if (output && output !== source) {
1753
1757
  try {
1754
- fs.writeFileSync(item.localUri, output, item.encoding || (item.encoding = 'utf-8'));
1758
+ fs.writeFileSync(item.localUri, output, item.encoding ||= 'utf-8');
1755
1759
  item.sourceUTF8 = output;
1756
1760
  }
1757
1761
  catch (err) {
@@ -1767,7 +1771,7 @@ class ChromeDocument extends Document {
1767
1771
  if (item.compress) {
1768
1772
  await host.compressFile(item);
1769
1773
  }
1770
- await Promise.all(Cloud.uploadAsset(state, item, item.mimeType));
1774
+ await Promise.all(Cloud.uploadAsset(state, item, { preferBuffer }));
1771
1775
  }
1772
1776
  }
1773
1777
  if (this.aborted) {
@@ -1780,7 +1784,7 @@ class ChromeDocument extends Document {
1780
1784
  if ((0, types_1.isArray)(cloudStorage)) {
1781
1785
  for (const storage of cloudStorage) {
1782
1786
  if (instance.hasCredential('storage', storage)) {
1783
- const { service, admin, bucket, upload } = storage;
1787
+ const { admin, bucket, upload } = storage;
1784
1788
  const website = admin?.configBucket?.website;
1785
1789
  if ((0, types_1.isPlainObject)(website) && bucket && upload) {
1786
1790
  let filename = joinPath(upload.pathname, upload.filename || path.basename(htmlFile.localUri));
@@ -1799,14 +1803,14 @@ class ChromeDocument extends Document {
1799
1803
  if (website.errorPath === true) {
1800
1804
  website.errorPath = filename;
1801
1805
  }
1802
- instance.setBucketWebsite(service, instance.getCredential(storage), bucket, website);
1806
+ instance.setBucketWebsite(storage.service, instance.getCredential(storage), bucket, website);
1803
1807
  }
1804
1808
  }
1805
1809
  }
1806
1810
  if (htmlFile.compress) {
1807
1811
  await host.compressFile(htmlFile);
1808
1812
  }
1809
- return Promise.all(Cloud.uploadAsset(state, htmlFile, 'text/html', true));
1813
+ return Promise.all(Cloud.uploadAsset(state, htmlFile, { preferBuffer, contentType: 'text/html', ignoreProcess: true }));
1810
1814
  }
1811
1815
  }
1812
1816
  return [];
@@ -1873,8 +1877,8 @@ class ChromeDocument extends Document {
1873
1877
  search = next.url.search;
1874
1878
  }
1875
1879
  }
1876
- search ?? (search = restoreSearchParams(asset.url?.search));
1877
- status && (status = status.filter(item => item.type >= types_1.STATUS_TYPE.FATAL && item.type <= types_1.STATUS_TYPE.WARN));
1880
+ search ??= restoreSearchParams(asset.url?.search);
1881
+ status &&= status.filter(item => item.type >= types_1.STATUS_TYPE.FATAL && item.type <= types_1.STATUS_TYPE.WARN);
1878
1882
  watch.send(types_1.WATCH_EVENT.MODIFIED, {
1879
1883
  action: pathname && watch.hot && !watch.main ? 'hot' : '',
1880
1884
  type: asset.mimeType,
@@ -2224,7 +2228,6 @@ class ChromeDocument extends Document {
2224
2228
  htmlFile.sourceUTF8 = source;
2225
2229
  }
2226
2230
  async setElementAttributes({ host, startTime, productionRelease }, domBase) {
2227
- var _a;
2228
2231
  const { moduleName, htmlFile } = this;
2229
2232
  const cloud = host.Cloud;
2230
2233
  const removeWatchReload = (item) => (0, types_1.isObject)(item.watch) && delete item.watch.reload;
@@ -2261,8 +2264,8 @@ class ChromeDocument extends Document {
2261
2264
  }
2262
2265
  if (uri && !(0, util_1.hasValue)(item.format, 'crossorigin') && item !== htmlFile) {
2263
2266
  if (cloud?.getStorage('upload', item.cloudStorage)) {
2264
- const inlineUrlCloud = item.inlineUrlCloud || (item.inlineUrlCloud = (0, types_1.generateUUID)());
2265
- ((_a = htmlFile).inlineUrlCloudMap || (_a.inlineUrlCloudMap = {}))[inlineUrlCloud] = productionRelease ? this.removeServerRoot(uri) : uri;
2267
+ const inlineUrlCloud = item.inlineUrlCloud ||= (0, types_1.generateUUID)();
2268
+ (htmlFile.inlineUrlCloudMap ||= {})[inlineUrlCloud] = productionRelease ? this.removeServerRoot(uri) : uri;
2266
2269
  uri = inlineUrlCloud;
2267
2270
  }
2268
2271
  if (!(0, util_1.hasValue)(item.format, 'webbundle')) {
@@ -2353,12 +2356,13 @@ class ChromeDocument extends Document {
2353
2356
  const cloud = host.Cloud;
2354
2357
  const sessionKey = (0, types_1.generateUUID)();
2355
2358
  const cacheData = Object.create(null);
2359
+ const coerceMap = {};
2356
2360
  const dataItems = [];
2357
2361
  const displayItems = [];
2358
2362
  this.dataSource.forEach(item => item.type === 'display' ? displayItems.push(item) : dataItems.push(item));
2359
2363
  const removeElement = (item, element) => {
2360
2364
  if (item.removeEmpty || item.type === 'display') {
2361
- (element || (element = new dom_1.HtmlElement(moduleName, item.element))).remove = true;
2365
+ (element ||= new dom_1.HtmlElement(moduleName, item.element)).remove = true;
2362
2366
  if (!domBase.write(element)) {
2363
2367
  this.writeFail('Unable to remove element', errorHtml(item.element), { type: 4, startTime });
2364
2368
  }
@@ -2371,7 +2375,7 @@ class ChromeDocument extends Document {
2371
2375
  this.writeFail(["Invalid credentials", item.source], err);
2372
2376
  }
2373
2377
  };
2374
- const checkObject = (item, data) => {
2378
+ const checkObject = (item, data, type) => {
2375
2379
  const { query, cascade } = item;
2376
2380
  if ((0, types_1.isString)(cascade)) {
2377
2381
  const result = data && (0, types_1.cascadeObject)(data, cascade, data);
@@ -2401,6 +2405,9 @@ class ChromeDocument extends Document {
2401
2405
  this.checkPackage(err, pkg, ["Unable to filter results", item.source]);
2402
2406
  }
2403
2407
  }
2408
+ if (type && !item.ignoreCoerce && (coerceMap[type] ??= this.settingsOf(type, 'coerce') === true)) {
2409
+ (0, types_1.coerceObject)(data);
2410
+ }
2404
2411
  }
2405
2412
  return Array.isArray(data) ? data : (0, types_1.isObject)(data) ? [data] : null;
2406
2413
  };
@@ -2418,7 +2425,7 @@ class ChromeDocument extends Document {
2418
2425
  const { service, credential } = item;
2419
2426
  if (cloud) {
2420
2427
  const key = service + '_' + (service === 'atlas' && item.uri || '') + '_' + asString(credential, true);
2421
- (batchMap[key] || (batchMap[key] = [])).push(item);
2428
+ (batchMap[key] ||= []).push(item);
2422
2429
  }
2423
2430
  else {
2424
2431
  errorCredential(item, (0, types_1.errorValue)("Cloud module not installed", service));
@@ -2448,7 +2455,7 @@ class ChromeDocument extends Document {
2448
2455
  key = core_1.ClientDb.keyOfResult(type, credential);
2449
2456
  break;
2450
2457
  }
2451
- (batchMap[key] || (batchMap[key] = [])).push(item);
2458
+ (batchMap[key] ||= []).push(item);
2452
2459
  }
2453
2460
  catch (err) {
2454
2461
  errorCredential(item, err);
@@ -2482,7 +2489,7 @@ class ChromeDocument extends Document {
2482
2489
  let result = new Array(length), errors;
2483
2490
  switch (type) {
2484
2491
  case 'cloud':
2485
- result = await cloud.getDatabaseBatchRows(batch, true, sessionKey).catch(err => {
2492
+ result = await cloud.getDatabaseBatchRows(batch, true, sessionKey).catch((err) => {
2486
2493
  this.abort(type);
2487
2494
  if (err instanceof Error) {
2488
2495
  cloud.addLog(this.aborted ? types_1.STATUS_TYPE.ERROR : types_1.STATUS_TYPE.WARN, errors = err);
@@ -2491,49 +2498,43 @@ class ChromeDocument extends Document {
2491
2498
  });
2492
2499
  break;
2493
2500
  case 'json':
2494
- if ((result[0] = checkObject(current, current.items)) === null) {
2501
+ if ((result[0] = checkObject(current, current.items, type)) === null) {
2495
2502
  this.abort(type);
2496
2503
  errorRemove(current, errorDataSource("Invalid parameters" + ' (items)', type));
2497
2504
  return;
2498
2505
  }
2499
- if (this.settingsOf(type, 'coerce') === true) {
2500
- (0, types_1.coerceObject)(result[0]);
2501
- }
2502
2506
  break;
2503
2507
  case 'uri':
2504
2508
  case 'local': {
2505
- const { ignoreCache, encoding = 'utf-8', options } = current;
2509
+ const encoding = current.encoding || 'utf-8';
2506
2510
  let content, target, data, cacheKey;
2507
2511
  if (type === 'local') {
2508
2512
  let location;
2509
- ({ pathname: target } = current);
2510
- if (target && ((location = this.resolveDir('data', target)) || host.canRead(location = path.resolve(target), { ownPermissionOnly: true }))) {
2511
- if (!ignoreCache && CACHE_DBRESULT.has(location)) {
2512
- data = getCacheItem(CACHE_DBRESULT, location);
2513
+ if (!(0, types_1.isString)(target = current.pathname) || !((location = this.resolveDir('data', target)) || host.canRead(location = path.resolve(target), { ownPermissionOnly: true }))) {
2514
+ this.abort(type);
2515
+ errorRemove(current, target ? errorDataSource('Not found', target) : errorDataSource('Not defined - ' + (this.settings.directory?.data ? 'file' : 'directory'), type));
2516
+ return;
2517
+ }
2518
+ if (!current.ignoreCache && CACHE_DBRESULT.has(location)) {
2519
+ data = getCacheItem(CACHE_DBRESULT, location);
2520
+ }
2521
+ else {
2522
+ if (current.ignoreCache === 1) {
2523
+ CACHE_DBRESULT.delete(location);
2513
2524
  }
2514
- else {
2515
- if (ignoreCache === 1) {
2516
- CACHE_DBRESULT.delete(location);
2525
+ if (!(data = cacheData[location])) {
2526
+ try {
2527
+ content = fs.readFileSync(location, encoding);
2528
+ cacheKey = location;
2517
2529
  }
2518
- if (!(data = cacheData[location])) {
2519
- try {
2520
- content = fs.readFileSync(location, encoding);
2521
- cacheKey = location;
2522
- }
2523
- catch (err) {
2524
- this.abort(type);
2525
- this.writeFail(["Unable to read file", path.basename(location)], err, { type: 32, startTime });
2526
- errorRemove(current);
2527
- return;
2528
- }
2530
+ catch (err) {
2531
+ this.abort(type);
2532
+ this.writeFail(["Unable to read file", path.basename(location)], err, { type: 32, startTime });
2533
+ errorRemove(current);
2534
+ return;
2529
2535
  }
2530
2536
  }
2531
2537
  }
2532
- else {
2533
- this.abort(type);
2534
- errorRemove(current, target ? errorDataSource('Not found', target) : errorDataSource('Not defined - ' + (this.settings.directory?.data ? 'file' : 'directory'), type));
2535
- return;
2536
- }
2537
2538
  }
2538
2539
  else if (!(0, types_1.isString)(target = current.uri)) {
2539
2540
  this.abort(type);
@@ -2556,11 +2557,11 @@ class ChromeDocument extends Document {
2556
2557
  return;
2557
2558
  }
2558
2559
  }
2559
- else if (!ignoreCache && CACHE_DBRESULT.has(target)) {
2560
+ else if (!current.ignoreCache && CACHE_DBRESULT.has(target)) {
2560
2561
  data = getCacheItem(CACHE_DBRESULT, target);
2561
2562
  }
2562
2563
  else {
2563
- if (ignoreCache === 1) {
2564
+ if (current.ignoreCache === 1) {
2564
2565
  CACHE_DBRESULT.delete(target);
2565
2566
  }
2566
2567
  if (!(data = cacheData[target])) {
@@ -2579,17 +2580,17 @@ class ChromeDocument extends Document {
2579
2580
  }
2580
2581
  else {
2581
2582
  const pathname = Document.resolveFile(target);
2582
- if (!ignoreCache && CACHE_DBRESULT.has(pathname)) {
2583
+ if (!current.ignoreCache && CACHE_DBRESULT.has(pathname)) {
2583
2584
  data = getCacheItem(CACHE_DBRESULT, pathname);
2584
2585
  }
2585
2586
  else {
2586
- if (ignoreCache === 1) {
2587
+ if (current.ignoreCache === 1) {
2587
2588
  CACHE_DBRESULT.delete(pathname);
2588
2589
  }
2589
2590
  if (!(data = cacheData[pathname])) {
2590
2591
  if (!host.canRead(pathname, { ownPermissionOnly: true })) {
2591
2592
  this.abort(type);
2592
- errorRemove(current, errorDataSource('Access denied', pathname));
2593
+ errorRemove(current, errorDataSource("Unsupported access", pathname));
2593
2594
  return;
2594
2595
  }
2595
2596
  try {
@@ -2611,11 +2612,11 @@ class ChromeDocument extends Document {
2611
2612
  if ((0, types_1.isString)(content)) {
2612
2613
  const { format = path.extname(target).substring(1) } = current;
2613
2614
  try {
2614
- data = this.tryParse(content, format, options);
2615
+ data = this.tryParse(content, format, current.options);
2615
2616
  }
2616
2617
  catch (err) {
2617
2618
  this.abort(type);
2618
- this.writeFail(['Unable to parse data source', format], err, { type: 4, startTime });
2619
+ this.writeFail(["Unable to parse inline object", format], err, { type: 4, startTime });
2619
2620
  errorRemove(current);
2620
2621
  return;
2621
2622
  }
@@ -2626,37 +2627,34 @@ class ChromeDocument extends Document {
2626
2627
  }
2627
2628
  if (!data) {
2628
2629
  this.abort(type);
2629
- errorRemove(current, errorDataSource(content !== null ? 'Invalid response' : 'Empty response', target));
2630
+ errorRemove(current, errorDataSource(content !== null ? "Invalid response" : "Unknown", target));
2630
2631
  return;
2631
2632
  }
2632
2633
  if (cacheKey) {
2633
2634
  setCacheData.call(this, current, data, cacheKey, cacheData);
2634
2635
  }
2635
- if ((result[0] = checkObject(current, data)) === null) {
2636
+ if ((result[0] = checkObject(current, data, type)) === null) {
2636
2637
  this.abort(type);
2637
2638
  errorRemove(current, errorDataSource('Invalid ' + (current.query ? 'query' : 'URI'), target));
2638
2639
  return;
2639
2640
  }
2640
- if (this.settingsOf(type, 'coerce') === true) {
2641
- (0, types_1.coerceObject)(result[0]);
2642
- }
2643
2641
  break;
2644
2642
  }
2645
2643
  case 'export': {
2646
- const ignoreCache = current.ignoreCache;
2647
2644
  const cacheKey = asString(current, true);
2648
- if (!ignoreCache && CACHE_DBRESULT.has(cacheKey)) {
2645
+ if (!current.ignoreCache && CACHE_DBRESULT.has(cacheKey)) {
2649
2646
  result[0] = getCacheItem(CACHE_DBRESULT, cacheKey);
2650
2647
  }
2651
2648
  else {
2652
- if (ignoreCache === 1) {
2649
+ if (current.ignoreCache === 1) {
2653
2650
  CACHE_DBRESULT.delete(cacheKey);
2654
2651
  }
2655
2652
  if (cacheKey in cacheData) {
2656
2653
  result[0] = cacheData[cacheKey];
2657
2654
  }
2658
2655
  else {
2659
- let { pathname, execute, params } = current, data, target, getData, hint;
2656
+ const { pathname, execute, params } = current;
2657
+ let data, target, getData, hint;
2660
2658
  if (typeof execute === 'function') {
2661
2659
  target = execute;
2662
2660
  }
@@ -2664,7 +2662,7 @@ class ChromeDocument extends Document {
2664
2662
  target = pathname;
2665
2663
  }
2666
2664
  else if ((0, types_1.isString)(pathname)) {
2667
- if ((pathname = pathname.trim()).startsWith('npm:')) {
2665
+ if (pathname.startsWith('npm:')) {
2668
2666
  target = pathname;
2669
2667
  hint = pathname;
2670
2668
  }
@@ -2677,7 +2675,7 @@ class ChromeDocument extends Document {
2677
2675
  }
2678
2676
  if (!getData) {
2679
2677
  const { settings, encoding, persist = true } = current;
2680
- target || (target = settings && this.settings.export?.[settings] || pathname);
2678
+ target ||= settings && this.settings.export?.[settings] || pathname;
2681
2679
  if (typeof target === 'function') {
2682
2680
  getData = target;
2683
2681
  hint = target.name;
@@ -2692,7 +2690,7 @@ class ChromeDocument extends Document {
2692
2690
  return;
2693
2691
  }
2694
2692
  try {
2695
- if (params && this.settingsOf(type, 'coerce') === true) {
2693
+ if (params && !current.ignoreCoerce && this.settingsOf(type, 'coerce') === true) {
2696
2694
  (0, types_1.coerceObject)(params);
2697
2695
  }
2698
2696
  if (getData["__cjs__"]) {
@@ -2736,136 +2734,129 @@ class ChromeDocument extends Document {
2736
2734
  break;
2737
2735
  }
2738
2736
  default:
2739
- if (db?.hasSource(type)) {
2740
- switch (type) {
2741
- case 'mongodb':
2742
- for (let j = 0; j < length; ++j) {
2743
- const cmd = batch[j];
2744
- cmd.cacheObjectKey = typeof cmd.cascade === 'string' ? cmd.cascade : '';
2745
- }
2746
- break;
2747
- case 'redis':
2748
- for (let j = 0; j < length; ++j) {
2749
- const cmd = batch[j];
2750
- const { search, key, query, cascade } = cmd;
2751
- if ((0, types_1.isObject)(search) && typeof search.schema === 'string') {
2752
- const pathname = this.resolveDir('schema', search.schema);
2753
- if (pathname) {
2754
- const ignoreCache = cmd.ignoreCache;
2755
- if (!ignoreCache && CACHE_LOCALFILE.has(pathname)) {
2756
- search.schema = getCacheItem(CACHE_LOCALFILE, pathname);
2737
+ if (!db?.hasSource(type)) {
2738
+ errorRemove(current, errorDataSource('Not found', type || "Unknown"));
2739
+ return;
2740
+ }
2741
+ switch (type) {
2742
+ case 'mongodb':
2743
+ for (let j = 0; j < length; ++j) {
2744
+ const cmd = batch[j];
2745
+ cmd.cacheObjectKey = typeof cmd.cascade === 'string' ? cmd.cascade : '';
2746
+ }
2747
+ break;
2748
+ case 'redis':
2749
+ for (let j = 0; j < length; ++j) {
2750
+ const cmd = batch[j];
2751
+ const { search, key, query, cascade } = cmd;
2752
+ if ((0, types_1.isObject)(search) && typeof search.schema === 'string') {
2753
+ const pathname = this.resolveDir('schema', search.schema);
2754
+ if (pathname) {
2755
+ if (!cmd.ignoreCache && CACHE_LOCALFILE.has(pathname)) {
2756
+ search.schema = getCacheItem(CACHE_LOCALFILE, pathname);
2757
+ }
2758
+ else {
2759
+ if (cmd.ignoreCache === 1) {
2760
+ CACHE_LOCALFILE.delete(pathname);
2757
2761
  }
2758
- else {
2759
- if (ignoreCache === 1) {
2760
- CACHE_LOCALFILE.delete(pathname);
2762
+ if (!(search.schema = cacheData[pathname])) {
2763
+ try {
2764
+ search.schema = loadLocalFile.call(this, current, pathname, cacheData, cmd.encoding);
2761
2765
  }
2762
- if (!(search.schema = cacheData[pathname])) {
2763
- try {
2764
- search.schema = loadLocalFile.call(this, current, pathname, cacheData, cmd.encoding);
2765
- }
2766
- catch (err) {
2767
- this.writeFail(['Unable to parse document', path.basename(pathname)], err instanceof Error ? errors = err : err, { startTime });
2768
- search.schema = undefined;
2769
- }
2766
+ catch (err) {
2767
+ this.writeFail(['Unable to parse document', path.basename(pathname)], err instanceof Error ? errors = err : err, { startTime });
2768
+ search.schema = undefined;
2770
2769
  }
2771
2770
  }
2772
2771
  }
2773
- else {
2774
- search.schema = undefined;
2775
- }
2776
2772
  }
2777
- if (key) {
2778
- cmd.cacheObjectKey = ((0, types_1.isString)(cascade) ? cascade : '') + '_' + ((0, types_1.isString)(query) ? query : '');
2773
+ else {
2774
+ search.schema = undefined;
2779
2775
  }
2780
2776
  }
2781
- break;
2782
- default:
2783
- if (db.hasSource(type, db.sourceType.SQL)) {
2784
- for (let j = 0; j < length; ++j) {
2785
- const cmd = batch[j];
2786
- const query = cmd.query;
2787
- if (typeof query === 'string' && query.endsWith('.sql')) {
2788
- const pathname = this.resolveDir('sql', query);
2789
- try {
2790
- if (pathname) {
2791
- const ignoreCache = cmd.ignoreCache;
2792
- if (!ignoreCache && CACHE_LOCALFILE.has(pathname)) {
2793
- cmd.query = getCacheItem(CACHE_LOCALFILE, pathname);
2777
+ if (key) {
2778
+ cmd.cacheObjectKey = ((0, types_1.isString)(cascade) ? cascade : '') + '_' + ((0, types_1.isString)(query) ? query : '');
2779
+ }
2780
+ }
2781
+ break;
2782
+ default:
2783
+ if (db.hasSource(type, db.sourceType.SQL)) {
2784
+ for (let j = 0; j < length; ++j) {
2785
+ const cmd = batch[j];
2786
+ const query = cmd.query;
2787
+ if (typeof query === 'string' && query.endsWith('.sql')) {
2788
+ const pathname = this.resolveDir('sql', query);
2789
+ try {
2790
+ if (pathname) {
2791
+ if (!cmd.ignoreCache && CACHE_LOCALFILE.has(pathname)) {
2792
+ cmd.query = getCacheItem(CACHE_LOCALFILE, pathname);
2793
+ }
2794
+ else {
2795
+ if (cmd.ignoreCache === 1) {
2796
+ CACHE_LOCALFILE.delete(pathname);
2794
2797
  }
2795
- else {
2796
- if (ignoreCache === 1) {
2797
- CACHE_LOCALFILE.delete(pathname);
2798
+ if (!(cmd.query = cacheData[pathname])) {
2799
+ const out = { content: '' };
2800
+ try {
2801
+ cmd.query = loadLocalFile.call(this, current, pathname, cacheData, cmd.encoding, out);
2798
2802
  }
2799
- if (!(cmd.query = cacheData[pathname])) {
2800
- const out = { content: '' };
2801
- try {
2802
- cmd.query = loadLocalFile.call(this, current, pathname, cacheData, cmd.encoding, out);
2803
- }
2804
- catch {
2805
- setCacheData.call(this, current, cmd.query = out.content, pathname, cacheData, true);
2806
- }
2803
+ catch {
2804
+ setCacheData.call(this, current, cmd.query = out.content, pathname, cacheData, true);
2807
2805
  }
2808
2806
  }
2809
2807
  }
2810
- else {
2811
- throw (0, types_1.errorMessage)(type, "File not found", query);
2812
- }
2813
2808
  }
2814
- catch (err) {
2815
- this.abort(type);
2816
- this.writeFail(["Unable to read file", pathname ? path.basename(pathname) : query], err, { startTime });
2817
- errorRemove(current);
2818
- return;
2809
+ else {
2810
+ throw (0, types_1.errorMessage)(type, "File not found", query);
2819
2811
  }
2820
2812
  }
2813
+ catch (err) {
2814
+ this.abort(type);
2815
+ this.writeFail(["Unable to read file", pathname ? path.basename(pathname) : query], err, { startTime });
2816
+ errorRemove(current);
2817
+ return;
2818
+ }
2821
2819
  }
2822
2820
  }
2823
- break;
2824
- }
2825
- try {
2826
- let coerce, cache;
2827
- if (type === 'mongodb' || type === 'redis') {
2828
- coerce = this.settingsOf(type, 'coerce');
2829
- cache = this.settingsOf(type, 'cache');
2830
2821
  }
2831
- const errorQuery = (err, data, commandType) => {
2832
- let message, aborting = true;
2833
- if (db.hasSource(type, db.sourceType.DOCUMENT)) {
2834
- message = (data.name ? data.name + ': ' : '') + (data.table || '');
2835
- }
2836
- else if (db.hasSource(type, db.sourceType.KEYVALUE)) {
2837
- aborting = commandType !== db.commandType.UPDATE;
2838
- message = asString(data.search || data.key);
2839
- }
2840
- else {
2841
- const credential = data.credential;
2842
- if ((0, types_1.isPlainObject)(credential)) {
2843
- message = credential.database;
2844
- }
2845
- }
2846
- if (data.willAbort) {
2847
- this.abort(undefined, err);
2848
- }
2849
- else if (aborting) {
2850
- this.abort(type, err);
2851
- }
2852
- if (err) {
2853
- this.writeFail(["Unable to execute query", message || "Unknown"], err instanceof Error ? errors = err : err, { type: 65536, startTime });
2822
+ break;
2823
+ }
2824
+ try {
2825
+ const errorQuery = (err, data, commandType) => {
2826
+ let message, aborting = true;
2827
+ if (db.hasSource(type, db.sourceType.DOCUMENT)) {
2828
+ message = (data.name ? data.name + ': ' : '') + (data.table || '');
2829
+ }
2830
+ else if (db.hasSource(type, db.sourceType.KEYVALUE)) {
2831
+ aborting = commandType !== db.commandType.UPDATE;
2832
+ message = asString(data.search || data.key);
2833
+ }
2834
+ else {
2835
+ const credential = data.credential;
2836
+ if ((0, types_1.isPlainObject)(credential)) {
2837
+ message = credential.database;
2854
2838
  }
2855
- return this.aborted;
2856
- };
2857
- const options = { coerce, cache, checkObject, sessionKey, connectOnce: length > 1, outCacheMiss: cacheMiss, errorQuery };
2858
- result = await db.executeBatchQuery(batch, options, result);
2859
- }
2860
- catch (err) {
2861
- this.abort(type);
2862
- const pkg = getPackageName(err);
2863
- errorClient(current, pkg && this.checkPackage(err, pkg) ? null : err);
2864
- }
2865
- break;
2839
+ }
2840
+ if (data.willAbort) {
2841
+ this.abort(undefined, err);
2842
+ }
2843
+ else if (aborting) {
2844
+ this.abort(type, err);
2845
+ }
2846
+ if (err) {
2847
+ this.writeFail(["Unable to execute query", message || "Unknown"], err instanceof Error ? errors = err : err, { type: 65536, startTime });
2848
+ }
2849
+ return this.aborted;
2850
+ };
2851
+ const options = { checkObject, sessionKey, connectOnce: length > 1, outCacheMiss: cacheMiss, errorQuery };
2852
+ result = await db.executeBatchQuery(batch, options, result);
2853
+ }
2854
+ catch (err) {
2855
+ this.abort(type);
2856
+ const pkg = getPackageName(err);
2857
+ errorClient(current, pkg && this.checkPackage(err, pkg) ? null : err);
2866
2858
  }
2867
- errorRemove(current, errorDataSource('Not found', type || "Unknown"));
2868
- return;
2859
+ break;
2869
2860
  }
2870
2861
  if (this.aborted) {
2871
2862
  resolve();
@@ -2873,9 +2864,9 @@ class ChromeDocument extends Document {
2873
2864
  }
2874
2865
  for (let i = 0, items; i < length; ++i) {
2875
2866
  const item = batch[i];
2876
- const { index, limit, ignoreEmpty, postQuery, whenEmpty } = item;
2867
+ const { index, limit, postQuery, whenEmpty } = item;
2877
2868
  const empty = (items = result[i]) === null;
2878
- if ((items || (items = [])).length === 0) {
2869
+ if ((items ||= []).length === 0) {
2879
2870
  if (whenEmpty) {
2880
2871
  const data = await checkData.call(this, item, whenEmpty, items, row => Array.isArray(row));
2881
2872
  if (data) {
@@ -2883,7 +2874,7 @@ class ChromeDocument extends Document {
2883
2874
  item.transactionFail = false;
2884
2875
  }
2885
2876
  }
2886
- if (ignoreEmpty && items.length === 0) {
2877
+ if (item.ignoreEmpty && items.length === 0) {
2887
2878
  continue;
2888
2879
  }
2889
2880
  }
@@ -2914,12 +2905,11 @@ class ChromeDocument extends Document {
2914
2905
  if (item.template) {
2915
2906
  const pathname = this.resolveDir('template', item.template);
2916
2907
  if (pathname) {
2917
- const ignoreCache = item.ignoreCache;
2918
- if (!ignoreCache && CACHE_LOCALFILE.has(pathname)) {
2908
+ if (!item.ignoreCache && CACHE_LOCALFILE.has(pathname)) {
2919
2909
  item.value = getCacheItem(CACHE_LOCALFILE, pathname);
2920
2910
  }
2921
2911
  else {
2922
- if (ignoreCache === 1) {
2912
+ if (item.ignoreCache === 1) {
2923
2913
  CACHE_LOCALFILE.delete(pathname);
2924
2914
  }
2925
2915
  if (!(item.value = cacheData[pathname])) {
@@ -2960,7 +2950,7 @@ class ChromeDocument extends Document {
2960
2950
  for (let j = 0, match; j < items.length; ++j) {
2961
2951
  const row = items[j];
2962
2952
  if ((0, types_1.isPlainObject)(row)) {
2963
- row.__index__ ?? (row.__index__ = j + 1);
2953
+ row.__index__ ??= j + 1;
2964
2954
  }
2965
2955
  let segment = template;
2966
2956
  while (match = REGEXP_TEMPLATECONDITIONAL.exec(segment)) {
@@ -3179,7 +3169,7 @@ class ChromeDocument extends Document {
3179
3169
  }
3180
3170
  }
3181
3171
  if (errors && item.removeEmpty) {
3182
- domElement.remove || (domElement.remove = true);
3172
+ domElement.remove ||= true;
3183
3173
  }
3184
3174
  }
3185
3175
  if (!domElement.remove) {
@@ -3207,7 +3197,7 @@ class ChromeDocument extends Document {
3207
3197
  else {
3208
3198
  if (!empty && item.type !== 'display' || item.transactionFail) {
3209
3199
  const emptyResponse = (value, service = item.source) => {
3210
- value || (value = "Unknown");
3200
+ value ||= "Unknown";
3211
3201
  return errors instanceof Error ? (0, types_1.errorMessage)(service, value, errors.message) : errorDataSource(service + ' -> Empty', value);
3212
3202
  };
3213
3203
  switch (item.source) {
@@ -3279,7 +3269,7 @@ class ChromeDocument extends Document {
3279
3269
  let value;
3280
3270
  if (data && (value = Document.asHash(data, { algorithm, encoding: item.encoding, digest: 'base64' }))) {
3281
3271
  attributes.integrity = algorithm + '-' + value;
3282
- attributes.crossorigin || (attributes.crossorigin = 'anonymous');
3272
+ attributes.crossorigin ||= 'anonymous';
3283
3273
  break;
3284
3274
  }
3285
3275
  throw (0, types_1.errorMessage)('hash', 'Source not found', item.filename);
@@ -3299,9 +3289,8 @@ class ChromeDocument extends Document {
3299
3289
  }
3300
3290
  }
3301
3291
  }
3302
- removeUnusedStyles(source, { useUnsafeCssReplace, usedVariables, usedFontFace, usedKeyframes, unusedStyles, unusedMedia, unusedContainer, unusedSupports, useSessionCache } = this.config) {
3303
- var _a;
3304
- if (!usedVariables && !usedFontFace && !usedKeyframes && !unusedStyles && !unusedMedia && !unusedContainer && !unusedSupports) {
3292
+ removeUnusedStyles(source, { useUnsafeCssReplace, usedVariables, usedFontFace, usedKeyframes, unusedStyles, unusedMedia, unusedSupports, unusedContainer, unusedScope, useSessionCache } = this.config) {
3293
+ if (!usedVariables && !usedFontFace && !usedKeyframes && !unusedStyles && !unusedMedia && !unusedContainer && !unusedSupports && !unusedScope) {
3305
3294
  return;
3306
3295
  }
3307
3296
  const queryMap = useSessionCache ? CACHE_QUERY : this._queryMap;
@@ -3407,15 +3396,17 @@ class ChromeDocument extends Document {
3407
3396
  }
3408
3397
  return selector.replace(/ +/g, getStringMany()) + getStringSome();
3409
3398
  };
3410
- const replaceUnunsed = (name, items, nesting) => {
3411
- for (let value of items) {
3412
- const key = name + '_' + (value = value.trim()) + (useUnsafeCssReplace ? '_1' : '');
3399
+ const replaceUnunsed = (name, items, nesting, increment = 1) => {
3400
+ for (let i = 0; i < items.length; i += increment) {
3401
+ const value = items[i].trim();
3402
+ let valueTo;
3403
+ const key = name + '_' + value + (increment === 2 && (valueTo = items[i + 1].trim()) ? '_' + valueTo : '') + (useUnsafeCssReplace ? '_1' : '');
3413
3404
  let pattern = queryMap.get(key), rule;
3414
3405
  if (!pattern) {
3415
3406
  let flags = 'gi', selector = '', revised;
3416
3407
  if (name === 'container') {
3417
- for (let i = 0, length = value.length, casing = true; i < length; i++) {
3418
- let ch = value[i];
3408
+ for (let j = 0, length = value.length, casing = true; j < length; j++) {
3409
+ let ch = value[j];
3419
3410
  if (!casing) {
3420
3411
  ch = ch.toLowerCase();
3421
3412
  }
@@ -3423,7 +3414,7 @@ class ChromeDocument extends Document {
3423
3414
  casing = false;
3424
3415
  }
3425
3416
  if (casing || ch < 'a' || ch > 'z') {
3426
- selector += value[i];
3417
+ selector += value[j];
3427
3418
  if (selector.endsWith(' not ')) {
3428
3419
  selector = selector.replace(/ not $/, ' `nN``oO``tT` ');
3429
3420
  }
@@ -3434,6 +3425,14 @@ class ChromeDocument extends Document {
3434
3425
  }
3435
3426
  flags = 'g';
3436
3427
  }
3428
+ else if (name === 'scope') {
3429
+ selector = `\\(${getStringSome() + parseSelector(value)}\\)`;
3430
+ if (valueTo) {
3431
+ selector += `${getStringMany()}[tT][oO]${getStringMany()}\\(${getStringSome() + parseSelector(valueTo)}\\)`;
3432
+ }
3433
+ flags = 'g';
3434
+ revised = true;
3435
+ }
3437
3436
  else if (name === 'supports' && /^selector\(/i.test(value)) {
3438
3437
  const startIndex = value.indexOf('(');
3439
3438
  const endIndex = value.lastIndexOf(')');
@@ -3460,25 +3459,18 @@ class ChromeDocument extends Document {
3460
3459
  pattern.lastIndex = 0;
3461
3460
  }
3462
3461
  while (rule = pattern.exec(current)) {
3463
- invalid: {
3464
- if (!nesting) {
3465
- for (let i = rule.index - 1; i > 0; --i) {
3466
- const ch = current[i];
3467
- if (ch === '}') {
3468
- break;
3469
- }
3470
- if (ch === '{') {
3471
- break invalid;
3472
- }
3473
- }
3474
- }
3475
- const [endIndex, trailing] = findClosingIndex(current, getEndIndex(rule), '{');
3476
- if (endIndex !== -1) {
3477
- current = spliceSource(current, rule.index, endIndex, pattern, rule[1], trailing);
3478
- (checkEmpty || (checkEmpty = {}))[name] = true;
3479
- modified = true;
3462
+ if (!nesting) {
3463
+ const block = Array.from(current.substring(0, rule.index).matchAll(/{|}/g));
3464
+ if (block.filter(open => open[0] === '{').length !== block.filter(close => close[0] === '}').length) {
3465
+ continue;
3480
3466
  }
3481
3467
  }
3468
+ const [endIndex, trailing] = findClosingIndex(current, getEndIndex(rule), '{');
3469
+ if (endIndex !== -1) {
3470
+ current = spliceSource(current, rule.index, endIndex, pattern, rule[1], trailing);
3471
+ (checkEmpty ||= {})[name] = true;
3472
+ modified = true;
3473
+ }
3482
3474
  }
3483
3475
  }
3484
3476
  };
@@ -3517,6 +3509,9 @@ class ChromeDocument extends Document {
3517
3509
  if (unusedContainer) {
3518
3510
  replaceUnunsed('container', unusedContainer, false);
3519
3511
  }
3512
+ if (unusedScope) {
3513
+ replaceUnunsed('scope', unusedScope.map(item => [item.start || '', item.end || '']).flat(), false, 2);
3514
+ }
3520
3515
  if (unusedStyles) {
3521
3516
  current = (function recurse(target, child) {
3522
3517
  let output = '', index = 0, pendingStart = 0, pendingEnd = 0, found = -1;
@@ -3668,7 +3663,7 @@ class ChromeDocument extends Document {
3668
3663
  }
3669
3664
  if (modified) {
3670
3665
  for (const name in checkEmpty) {
3671
- const pattern = CACHE_ATRULES[_a = name + (useUnsafeCssReplace ? '_1' : '')] || (CACHE_ATRULES[_a] = new RegExp(`(\\s*)@${name}[^{]*{${getStringSome()}}` + dom_1.DomWriter.PATTERN_TRAILINGSPACE, 'gi'));
3666
+ const pattern = CACHE_ATRULES[name + (useUnsafeCssReplace ? '_1' : '')] ||= new RegExp(`(\\s*)@${name}[^{]*{${getStringSome()}}` + dom_1.DomWriter.PATTERN_TRAILINGSPACE, 'gi');
3672
3667
  while (match = pattern.exec(current)) {
3673
3668
  current = spliceSource(current, match.index, getEndIndex(match), pattern, match[1], match[2]);
3674
3669
  }
@@ -3733,10 +3728,7 @@ class ChromeDocument extends Document {
3733
3728
  return [];
3734
3729
  }
3735
3730
  get settings() {
3736
- var _a;
3737
- return (_a = this.module).settings || (_a.settings = {});
3731
+ return this.module.settings ||= {};
3738
3732
  }
3739
3733
  }
3740
- ChromeDocument.INTERNAL_ASSIGNUUID = "__assign__";
3741
- ChromeDocument.INTERNAL_SERVERROOT = "__serverroot__";
3742
3734
  module.exports = ChromeDocument;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-r/chrome",
3
- "version": "0.6.6",
3
+ "version": "0.7.0",
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.8.7",
24
- "@e-mc/core": "^0.8.7",
25
- "@e-mc/document": "^0.8.7",
26
- "@e-mc/types": "^0.8.7"
23
+ "@e-mc/cloud": "^0.9.0",
24
+ "@e-mc/core": "^0.9.0",
25
+ "@e-mc/document": "^0.9.0",
26
+ "@e-mc/types": "^0.9.0"
27
27
  }
28
28
  }
package/types/index.d.ts CHANGED
@@ -26,10 +26,10 @@ interface DocumentDirectory extends IDocumentDirectory {
26
26
  }
27
27
 
28
28
  interface DocumentComponentExtended<T> extends DbSourceDataType<T> {
29
- json?: T;
30
29
  uri?: T;
31
30
  local?: T;
32
31
  export?: T;
32
+ json?: T;
33
33
  }
34
34
 
35
35
  interface DocumentComponentOptions<T> extends IDocumentComponentOptions, DocumentComponentExtended<DocumentComponentOption<T>> {}
@@ -56,7 +56,7 @@ export interface FinalizeProcessing<T extends IFileManager<U>, U extends Documen
56
56
  readonly startTime: LogTime;
57
57
  readonly hashed: Set<DocumentAsset>;
58
58
  readonly contentMap: StringMap;
59
- readonly bufferMap: ObjectMap<BufferContent>;
59
+ readonly bufferMap: ObjectMap<Bufferable>;
60
60
  readonly cacheMiss: string[];
61
61
  readonly productionRelease: Undef<true>;
62
62
  }
@@ -124,4 +124,4 @@ export interface ChromeDocumentConstructor<T extends IFileManager<U>, U extends
124
124
  INTERNAL_SERVERROOT: string;
125
125
  readonly prototype: IChromeDocument<T, U>;
126
126
  new(module?: DocumentModule, ...args: unknown[]): IChromeDocument<T, U>;
127
- }
127
+ }
@@ -1,4 +1,4 @@
1
- import type { AttributeAction, ConditionProperty, CssConditionData, ElementAction, ExcludeAction, FileAsset, FromAction, HashAction, DataSource as IDataSource, ImportAction, MetadataAction, ViewEngine, XmlTagNode } from '@e-mc/types/lib/squared';
1
+ import type { AttributeAction, ConditionProperty, CssConditionData, ElementAction, ExcludeAction, FileAsset, FromAction, HashAction, DataSource as IDataSource, ImportAction, MetadataAction, ViewEngine } from '@e-mc/types/lib/squared';
2
2
 
3
3
  import type { UploadAction } from '@e-mc/types/lib/cloud';
4
4
  import type { CascadeAction, DbSource } from '@e-mc/types/lib/db';
@@ -18,11 +18,19 @@ interface DataObject extends CascadeAction {
18
18
  options?: PlainObject;
19
19
  }
20
20
 
21
+ interface ScopeData {
22
+ start: Null<string>;
23
+ end: Null<string>;
24
+ }
25
+
21
26
  export interface UserAgentData {
22
27
  platform: string;
28
+ name: string;
23
29
  brand: string;
24
30
  browser: number;
25
31
  version: Null<number[]>;
32
+ majorVersion: number;
33
+ mobile: boolean;
26
34
  }
27
35
 
28
36
  export interface DocumentOutput {
@@ -73,8 +81,9 @@ export interface CssRuleData {
73
81
  usedKeyframes?: string[];
74
82
  unusedStyles?: string[];
75
83
  unusedMedia?: string[];
76
- unusedContainer?: string[];
77
84
  unusedSupports?: string[];
85
+ unusedContainer?: string[];
86
+ unusedScope?: ScopeData[];
78
87
  unusedAtRules?: UnusedAtRule[];
79
88
  }
80
89
 
@@ -88,13 +97,13 @@ export interface UnusedAtRule {
88
97
 
89
98
  export interface DataSource<T = string> extends IDataSource<T>, ElementAction {
90
99
  source: "cloud" | "json" | "uri" | "local" | "export" | DbSource;
91
- element?: XmlTagNode;
92
100
  type?: "text" | "attribute" | "display";
93
101
  dynamic?: boolean;
94
- value?: StringOfArray | ObjectMap<unknown>;
102
+ value?: ArrayOf<string> | AnyObject;
95
103
  template?: string;
96
104
  viewEngine?: ViewEngine | string;
97
105
  ignoreEmpty?: boolean;
106
+ ignoreCoerce?: boolean;
98
107
  }
99
108
 
100
109
  export interface TextDataSource extends DataSource {