@noy-db/hub 0.2.0-pre.27 → 0.2.0-pre.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/aggregate/index.cjs +7 -0
- package/dist/aggregate/index.cjs.map +1 -1
- package/dist/aggregate/index.d.cts +2 -2
- package/dist/aggregate/index.d.ts +2 -2
- package/dist/aggregate/index.js +2 -2
- package/dist/attestation/index.cjs.map +1 -1
- package/dist/attestation/index.d.cts +3 -3
- package/dist/attestation/index.d.ts +3 -3
- package/dist/attestation/index.js +4 -4
- package/dist/blobs/index.cjs.map +1 -1
- package/dist/blobs/index.d.cts +5 -5
- package/dist/blobs/index.d.ts +5 -5
- package/dist/blobs/index.js +4 -4
- package/dist/bundle/index.cjs +83 -5
- package/dist/bundle/index.cjs.map +1 -1
- package/dist/bundle/index.d.cts +5 -5
- package/dist/bundle/index.d.ts +5 -5
- package/dist/bundle/index.js +8 -8
- package/dist/{chunk-PS6PSEZL.js → chunk-2M62POB5.js} +3 -3
- package/dist/{chunk-C7UIT5XY.js → chunk-345PYZD6.js} +2 -2
- package/dist/{chunk-KSKKLVPA.js → chunk-3LHTFCU2.js} +113 -41
- package/dist/chunk-3LHTFCU2.js.map +1 -0
- package/dist/{chunk-KA5A5CSD.js → chunk-42EGY2FQ.js} +3 -3
- package/dist/{chunk-7DDTFGXY.js → chunk-4FHKQDHN.js} +2 -2
- package/dist/{chunk-KD253AI5.js → chunk-6LD37AMK.js} +22 -3
- package/dist/chunk-6LD37AMK.js.map +1 -0
- package/dist/{chunk-6H4CAHMQ.js → chunk-7GKDVWMD.js} +2 -2
- package/dist/{chunk-6ZKXFMUG.js → chunk-7TBCLM52.js} +2 -2
- package/dist/{chunk-VJNV2GRF.js → chunk-AHDQYG7P.js} +3 -3
- package/dist/{chunk-RRCRITDM.js → chunk-DCYWBKQ2.js} +2 -2
- package/dist/{chunk-K6PCTYAH.js → chunk-DMWUOV7X.js} +2 -2
- package/dist/{chunk-CVTPNW2Y.js → chunk-DQ6XF2K2.js} +6 -6
- package/dist/{chunk-5EITJMUJ.js → chunk-ENC4C6XW.js} +3 -3
- package/dist/{chunk-BOMH3637.js → chunk-GVEUI7VR.js} +2 -2
- package/dist/{chunk-WVYL6HM7.js → chunk-HI7FY7QZ.js} +2 -2
- package/dist/{chunk-PFKAT4NT.js → chunk-HQ242WNG.js} +3 -3
- package/dist/{chunk-HAKEZTA7.js → chunk-IMY4FXYE.js} +3 -3
- package/dist/{chunk-SID2NJNF.js → chunk-JEQB2KVI.js} +2 -2
- package/dist/{chunk-Z3BJF7SF.js → chunk-M2VZQ24Q.js} +2 -2
- package/dist/{chunk-2NYVA6FW.js → chunk-PPF7Z2YQ.js} +2 -2
- package/dist/{chunk-IWGVH2RR.js → chunk-QBC2TZHC.js} +3 -3
- package/dist/{chunk-AD6RNBAW.js → chunk-QSLIT4JZ.js} +1 -1
- package/dist/chunk-QSLIT4JZ.js.map +1 -0
- package/dist/{chunk-BMDVFBCL.js → chunk-RG5KLMEU.js} +2 -2
- package/dist/{chunk-DONPLWRC.js → chunk-SWGVCSIY.js} +2 -2
- package/dist/{chunk-LXA2E3VI.js → chunk-VSL3W2MO.js} +2 -2
- package/dist/{chunk-6M5JKTUQ.js → chunk-WH7G2YEE.js} +2 -2
- package/dist/{chunk-I2RX62RX.js → chunk-YYLFXX2K.js} +2 -2
- package/dist/consent/index.d.cts +4 -4
- package/dist/consent/index.d.ts +4 -4
- package/dist/{decrypt-partition-CptDdcCx.d.ts → decrypt-partition-BtGtE-19.d.ts} +1 -1
- package/dist/{decrypt-partition-DmkeOB4I.d.cts → decrypt-partition-Cqi5gcOl.d.cts} +1 -1
- package/dist/derivations/index.d.cts +5 -5
- package/dist/derivations/index.d.ts +5 -5
- package/dist/{dev-unlock-DUTLA3Sc.d.cts → dev-unlock-Cts_iiVv.d.cts} +1 -1
- package/dist/{dev-unlock-Y9znMkQ2.d.ts → dev-unlock-D0p9cQzN.d.ts} +1 -1
- package/dist/{executor-BIW4FT5R.js → executor-PJHMRZWJ.js} +4 -4
- package/dist/{fanout-sidecar-OC4QVTS2.js → fanout-sidecar-DSBVAR2P.js} +2 -2
- package/dist/forget/index.js +2 -2
- package/dist/guards/index.d.cts +5 -5
- package/dist/guards/index.d.ts +5 -5
- package/dist/{hash-Btl9IvQS.d.ts → hash-BtDtwguU.d.ts} +1 -1
- package/dist/{hash-DFK7cGdo.d.cts → hash-DA75XwW2.d.cts} +1 -1
- package/dist/history/index.cjs.map +1 -1
- package/dist/history/index.d.cts +5 -5
- package/dist/history/index.d.ts +5 -5
- package/dist/history/index.js +3 -3
- package/dist/i18n/index.cjs +98 -1
- package/dist/i18n/index.cjs.map +1 -1
- package/dist/i18n/index.d.cts +4 -4
- package/dist/i18n/index.d.ts +4 -4
- package/dist/i18n/index.js +83 -4
- package/dist/i18n/index.js.map +1 -1
- package/dist/{index-wRwJVVJQ.d.ts → index-BidHvmWf.d.ts} +3 -3
- package/dist/{index-CqzZml-D.d.cts → index-CP24aYCp.d.cts} +3 -3
- package/dist/{index-DoxKSsMj.d.cts → index-CVnt2Qmq.d.cts} +1 -1
- package/dist/{index-LaexBi3v.d.ts → index-DxBNV54L.d.ts} +1 -1
- package/dist/index.cjs +95 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -14
- package/dist/index.d.ts +14 -14
- package/dist/index.js +24 -24
- package/dist/{issue-ZZ2XPOGP.js → issue-JSGGSVY4.js} +4 -4
- package/dist/kernel/index.d.cts +4 -4
- package/dist/kernel/index.d.ts +4 -4
- package/dist/kernel/index.js +4 -4
- package/dist/{ledger-XQ4KVFQ6.js → ledger-PLMSH7LD.js} +3 -3
- package/dist/materialized-views/index.cjs +7 -0
- package/dist/materialized-views/index.cjs.map +1 -1
- package/dist/materialized-views/index.d.cts +5 -5
- package/dist/materialized-views/index.d.ts +5 -5
- package/dist/materialized-views/index.js +4 -4
- package/dist/{mime-magic-OiPT1qed.d.ts → mime-magic--NcogI82.d.ts} +1 -1
- package/dist/{mime-magic-Co4Pyj-O.d.cts → mime-magic-i2VSlkPM.d.cts} +1 -1
- package/dist/noydb-PHXA5E6I.js +39 -0
- package/dist/overlay-views/index.d.cts +5 -5
- package/dist/overlay-views/index.d.ts +5 -5
- package/dist/periods/index.cjs.map +1 -1
- package/dist/periods/index.d.cts +4 -4
- package/dist/periods/index.d.ts +4 -4
- package/dist/periods/index.js +3 -3
- package/dist/{public-envelope-O6X6AUUS.js → public-envelope-7MTH2PVE.js} +3 -3
- package/dist/query/index.cjs +7 -0
- package/dist/query/index.cjs.map +1 -1
- package/dist/query/index.d.cts +2 -2
- package/dist/query/index.d.ts +2 -2
- package/dist/query/index.js +3 -3
- package/dist/{revoke-QJ2HUM4W.js → revoke-DBAGKIDA.js} +4 -4
- package/dist/session/index.d.cts +5 -5
- package/dist/session/index.d.ts +5 -5
- package/dist/shadow/index.d.cts +4 -4
- package/dist/shadow/index.d.ts +4 -4
- package/dist/{signer-SCJ6C6HQ.js → signer-ADFJNS5W.js} +3 -3
- package/dist/snapshots/index.d.cts +4 -4
- package/dist/snapshots/index.d.ts +4 -4
- package/dist/snapshots/index.js +3 -3
- package/dist/{stale-KKCHF2VB.js → stale-BCIE3SMC.js} +2 -2
- package/dist/store/index.d.cts +4 -4
- package/dist/store/index.d.ts +4 -4
- package/dist/{strategy-YQ1qJWyq.d.ts → strategy-BoITAb2H.d.ts} +20 -1
- package/dist/{strategy-D1zjEV3n.d.cts → strategy-DDNvt_UD.d.cts} +20 -1
- package/dist/sync/index.cjs.map +1 -1
- package/dist/sync/index.d.cts +3 -3
- package/dist/sync/index.d.ts +3 -3
- package/dist/sync/index.js +2 -2
- package/dist/team/index.cjs.map +1 -1
- package/dist/team/index.d.cts +4 -4
- package/dist/team/index.d.ts +4 -4
- package/dist/team/index.js +5 -5
- package/dist/{transition-guard-CJmb8O8q.d.ts → transition-guard-BZhOlrFT.d.ts} +1 -1
- package/dist/{transition-guard-Dzj68JWC.d.cts → transition-guard-Bekgaxux.d.cts} +1 -1
- package/dist/tx/index.d.cts +4 -4
- package/dist/tx/index.d.ts +4 -4
- package/dist/{types-CkSWJt0H.d.ts → types-84nsWSDF.d.ts} +45 -4
- package/dist/{types-CwrTuYFI.d.cts → types-B_eCkuEI.d.cts} +45 -4
- package/dist/{with-materialized-view-BVfcPlaE.d.ts → with-materialized-view-CAMGQroY.d.ts} +1 -1
- package/dist/{with-materialized-view-dPG213gd.d.cts → with-materialized-view-DKMaZmkJ.d.cts} +1 -1
- package/dist/{with-overlayed-view-CJ2UDBol.d.cts → with-overlayed-view--lWXImbV.d.cts} +1 -1
- package/dist/{with-overlayed-view-zYPQzGGh.d.ts → with-overlayed-view-FnOf1v6H.d.ts} +1 -1
- package/dist/{with-rollup-B_zbRi3f.d.cts → with-rollup-C5875Ad5.d.cts} +1 -1
- package/dist/{with-rollup-BvaJefEs.d.ts → with-rollup-xi-mkY6Y.d.ts} +1 -1
- package/package.json +3 -3
- package/dist/chunk-AD6RNBAW.js.map +0 -1
- package/dist/chunk-KD253AI5.js.map +0 -1
- package/dist/chunk-KSKKLVPA.js.map +0 -1
- package/dist/noydb-EY52NVH4.js +0 -39
- /package/dist/{chunk-PS6PSEZL.js.map → chunk-2M62POB5.js.map} +0 -0
- /package/dist/{chunk-C7UIT5XY.js.map → chunk-345PYZD6.js.map} +0 -0
- /package/dist/{chunk-KA5A5CSD.js.map → chunk-42EGY2FQ.js.map} +0 -0
- /package/dist/{chunk-7DDTFGXY.js.map → chunk-4FHKQDHN.js.map} +0 -0
- /package/dist/{chunk-6H4CAHMQ.js.map → chunk-7GKDVWMD.js.map} +0 -0
- /package/dist/{chunk-6ZKXFMUG.js.map → chunk-7TBCLM52.js.map} +0 -0
- /package/dist/{chunk-VJNV2GRF.js.map → chunk-AHDQYG7P.js.map} +0 -0
- /package/dist/{chunk-RRCRITDM.js.map → chunk-DCYWBKQ2.js.map} +0 -0
- /package/dist/{chunk-K6PCTYAH.js.map → chunk-DMWUOV7X.js.map} +0 -0
- /package/dist/{chunk-CVTPNW2Y.js.map → chunk-DQ6XF2K2.js.map} +0 -0
- /package/dist/{chunk-5EITJMUJ.js.map → chunk-ENC4C6XW.js.map} +0 -0
- /package/dist/{chunk-BOMH3637.js.map → chunk-GVEUI7VR.js.map} +0 -0
- /package/dist/{chunk-WVYL6HM7.js.map → chunk-HI7FY7QZ.js.map} +0 -0
- /package/dist/{chunk-PFKAT4NT.js.map → chunk-HQ242WNG.js.map} +0 -0
- /package/dist/{chunk-HAKEZTA7.js.map → chunk-IMY4FXYE.js.map} +0 -0
- /package/dist/{chunk-SID2NJNF.js.map → chunk-JEQB2KVI.js.map} +0 -0
- /package/dist/{chunk-Z3BJF7SF.js.map → chunk-M2VZQ24Q.js.map} +0 -0
- /package/dist/{chunk-2NYVA6FW.js.map → chunk-PPF7Z2YQ.js.map} +0 -0
- /package/dist/{chunk-IWGVH2RR.js.map → chunk-QBC2TZHC.js.map} +0 -0
- /package/dist/{chunk-BMDVFBCL.js.map → chunk-RG5KLMEU.js.map} +0 -0
- /package/dist/{chunk-DONPLWRC.js.map → chunk-SWGVCSIY.js.map} +0 -0
- /package/dist/{chunk-LXA2E3VI.js.map → chunk-VSL3W2MO.js.map} +0 -0
- /package/dist/{chunk-6M5JKTUQ.js.map → chunk-WH7G2YEE.js.map} +0 -0
- /package/dist/{chunk-I2RX62RX.js.map → chunk-YYLFXX2K.js.map} +0 -0
- /package/dist/{executor-BIW4FT5R.js.map → executor-PJHMRZWJ.js.map} +0 -0
- /package/dist/{fanout-sidecar-OC4QVTS2.js.map → fanout-sidecar-DSBVAR2P.js.map} +0 -0
- /package/dist/{issue-ZZ2XPOGP.js.map → issue-JSGGSVY4.js.map} +0 -0
- /package/dist/{ledger-XQ4KVFQ6.js.map → ledger-PLMSH7LD.js.map} +0 -0
- /package/dist/{noydb-EY52NVH4.js.map → noydb-PHXA5E6I.js.map} +0 -0
- /package/dist/{public-envelope-O6X6AUUS.js.map → public-envelope-7MTH2PVE.js.map} +0 -0
- /package/dist/{revoke-QJ2HUM4W.js.map → revoke-DBAGKIDA.js.map} +0 -0
- /package/dist/{signer-SCJ6C6HQ.js.map → signer-ADFJNS5W.js.map} +0 -0
- /package/dist/{stale-KKCHF2VB.js.map → stale-BCIE3SMC.js.map} +0 -0
package/dist/i18n/index.d.cts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
export { I as I18nMap, a as I18nTextDescriptor, b as I18nTextOptions, L as Layer, O as OnMissing, c as OnMissingPolicy, R as ResolveI18nOptions, d as applyI18nLocale, g as getAtPath, i as i18nText, e as isI18nTextDescriptor, r as resolveI18nText, f as resolvePolicy, s as setAtPathInPlace, v as validateI18nTextValue } from '../strategy-
|
|
2
|
-
import { I as I18nStrategy } from '../types-
|
|
3
|
-
export { D as DICT_COLLECTION_PREFIX, a as DictEntry, b as DictKeyDescriptor, c as DictionaryHandle, d as DictionaryOptions, S as ScriptWarning, e as StaticDictDescriptor, f as dictCollectionName, g as dictKey, h as enforceScript, i as inferScripts, j as isDictCollectionName, k as isDictKeyDescriptor, l as isStaticDictDescriptor, s as staticDict } from '../types-
|
|
1
|
+
export { I as I18nMap, a as I18nTextDescriptor, b as I18nTextOptions, L as Layer, O as OnMissing, c as OnMissingPolicy, R as ResolveI18nOptions, d as applyI18nLocale, g as getAtPath, i as i18nText, e as isI18nTextDescriptor, r as resolveI18nText, f as resolvePolicy, s as setAtPathInPlace, h as stripI18nFilled, v as validateI18nTextValue } from '../strategy-DDNvt_UD.cjs';
|
|
2
|
+
import { I as I18nStrategy } from '../types-B_eCkuEI.cjs';
|
|
3
|
+
export { D as DICT_COLLECTION_PREFIX, a as DictEntry, b as DictKeyDescriptor, c as DictionaryHandle, d as DictionaryOptions, S as ScriptWarning, e as StaticDictDescriptor, f as dictCollectionName, g as dictKey, h as enforceScript, i as inferScripts, j as isDictCollectionName, k as isDictKeyDescriptor, l as isStaticDictDescriptor, s as staticDict } from '../types-B_eCkuEI.cjs';
|
|
4
4
|
export { D as DictKeyInUseError, a as DictKeyMissingError, L as LocaleNotSpecifiedError, M as MissingTranslationError, R as ReservedCollectionNameError, S as ScriptViolationError, b as StaticDictReadonlyError, T as TranslatorNotConfiguredError, U as UnknownDictCodeError } from '../errors-Dwk2k1xY.cjs';
|
|
5
5
|
import '../lazy-builder-eYZzLEL1.cjs';
|
|
6
6
|
import '../predicate-BmhBSPCH.cjs';
|
|
7
7
|
import '../strategy-BSxFXGzb.cjs';
|
|
8
8
|
import '../index-BMmajblo.cjs';
|
|
9
|
-
import '../index-
|
|
9
|
+
import '../index-CVnt2Qmq.cjs';
|
|
10
10
|
import '@noy-db/attestation';
|
|
11
11
|
|
|
12
12
|
/**
|
package/dist/i18n/index.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
export { I as I18nMap, a as I18nTextDescriptor, b as I18nTextOptions, L as Layer, O as OnMissing, c as OnMissingPolicy, R as ResolveI18nOptions, d as applyI18nLocale, g as getAtPath, i as i18nText, e as isI18nTextDescriptor, r as resolveI18nText, f as resolvePolicy, s as setAtPathInPlace, v as validateI18nTextValue } from '../strategy-
|
|
2
|
-
import { I as I18nStrategy } from '../types-
|
|
3
|
-
export { D as DICT_COLLECTION_PREFIX, a as DictEntry, b as DictKeyDescriptor, c as DictionaryHandle, d as DictionaryOptions, S as ScriptWarning, e as StaticDictDescriptor, f as dictCollectionName, g as dictKey, h as enforceScript, i as inferScripts, j as isDictCollectionName, k as isDictKeyDescriptor, l as isStaticDictDescriptor, s as staticDict } from '../types-
|
|
1
|
+
export { I as I18nMap, a as I18nTextDescriptor, b as I18nTextOptions, L as Layer, O as OnMissing, c as OnMissingPolicy, R as ResolveI18nOptions, d as applyI18nLocale, g as getAtPath, i as i18nText, e as isI18nTextDescriptor, r as resolveI18nText, f as resolvePolicy, s as setAtPathInPlace, h as stripI18nFilled, v as validateI18nTextValue } from '../strategy-BoITAb2H.js';
|
|
2
|
+
import { I as I18nStrategy } from '../types-84nsWSDF.js';
|
|
3
|
+
export { D as DICT_COLLECTION_PREFIX, a as DictEntry, b as DictKeyDescriptor, c as DictionaryHandle, d as DictionaryOptions, S as ScriptWarning, e as StaticDictDescriptor, f as dictCollectionName, g as dictKey, h as enforceScript, i as inferScripts, j as isDictCollectionName, k as isDictKeyDescriptor, l as isStaticDictDescriptor, s as staticDict } from '../types-84nsWSDF.js';
|
|
4
4
|
export { D as DictKeyInUseError, a as DictKeyMissingError, L as LocaleNotSpecifiedError, M as MissingTranslationError, R as ReservedCollectionNameError, S as ScriptViolationError, b as StaticDictReadonlyError, T as TranslatorNotConfiguredError, U as UnknownDictCodeError } from '../errors-Dwk2k1xY.js';
|
|
5
5
|
import '../lazy-builder-ChSqcF5t.js';
|
|
6
6
|
import '../predicate-BmhBSPCH.js';
|
|
7
7
|
import '../strategy-BSxFXGzb.js';
|
|
8
8
|
import '../index-BMmajblo.js';
|
|
9
|
-
import '../index-
|
|
9
|
+
import '../index-DxBNV54L.js';
|
|
10
10
|
import '@noy-db/attestation';
|
|
11
11
|
|
|
12
12
|
/**
|
package/dist/i18n/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
isDictKeyDescriptor,
|
|
8
8
|
isStaticDictDescriptor,
|
|
9
9
|
staticDict
|
|
10
|
-
} from "../chunk-
|
|
10
|
+
} from "../chunk-HQ242WNG.js";
|
|
11
11
|
import {
|
|
12
12
|
applyI18nLocale,
|
|
13
13
|
enforceScript,
|
|
@@ -18,11 +18,12 @@ import {
|
|
|
18
18
|
resolveI18nText,
|
|
19
19
|
resolvePolicy,
|
|
20
20
|
setAtPathInPlace,
|
|
21
|
+
stripI18nFilled,
|
|
21
22
|
validateI18nTextValue
|
|
22
|
-
} from "../chunk-
|
|
23
|
-
import "../chunk-
|
|
23
|
+
} from "../chunk-6LD37AMK.js";
|
|
24
|
+
import "../chunk-VSL3W2MO.js";
|
|
24
25
|
import "../chunk-PDVP3C2I.js";
|
|
25
|
-
import "../chunk-
|
|
26
|
+
import "../chunk-QSLIT4JZ.js";
|
|
26
27
|
import "../chunk-7JSP3E67.js";
|
|
27
28
|
import {
|
|
28
29
|
DictKeyInUseError,
|
|
@@ -36,12 +37,89 @@ import {
|
|
|
36
37
|
UnknownDictCodeError
|
|
37
38
|
} from "../chunk-DDOYOMAD.js";
|
|
38
39
|
|
|
40
|
+
// src/i18n/densify.ts
|
|
41
|
+
var MARKER = "_i18nFilled";
|
|
42
|
+
function priorFilled(prior, field) {
|
|
43
|
+
if (!prior) return /* @__PURE__ */ new Set();
|
|
44
|
+
const marker = prior[MARKER];
|
|
45
|
+
return new Set(marker?.[field] ?? []);
|
|
46
|
+
}
|
|
47
|
+
function singleLeaf(record, field) {
|
|
48
|
+
const leaves = getAtPath(record, field);
|
|
49
|
+
if (leaves.length !== 1) return void 0;
|
|
50
|
+
const leaf = leaves[0];
|
|
51
|
+
if (!leaf || typeof leaf !== "object" || Array.isArray(leaf)) return void 0;
|
|
52
|
+
return leaf;
|
|
53
|
+
}
|
|
54
|
+
function computeExemptFills(prior, incoming, fields) {
|
|
55
|
+
const out = /* @__PURE__ */ new Map();
|
|
56
|
+
if (!prior) return out;
|
|
57
|
+
for (const field of Object.keys(fields)) {
|
|
58
|
+
const filled = priorFilled(prior, field);
|
|
59
|
+
if (filled.size === 0) continue;
|
|
60
|
+
const priorLeaf = singleLeaf(prior, field);
|
|
61
|
+
const incLeaf = singleLeaf(incoming, field);
|
|
62
|
+
if (!priorLeaf || !incLeaf) continue;
|
|
63
|
+
const exempt = /* @__PURE__ */ new Set();
|
|
64
|
+
for (const loc of filled) {
|
|
65
|
+
if (incLeaf[loc] !== void 0 && incLeaf[loc] !== "" && incLeaf[loc] === priorLeaf[loc]) {
|
|
66
|
+
exempt.add(loc);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (exempt.size > 0) out.set(field, exempt);
|
|
70
|
+
}
|
|
71
|
+
return out;
|
|
72
|
+
}
|
|
73
|
+
function densify(record, prior, fields) {
|
|
74
|
+
let marker = record[MARKER];
|
|
75
|
+
for (const [field, descriptor] of Object.entries(fields)) {
|
|
76
|
+
const leaf = singleLeaf(record, field);
|
|
77
|
+
if (!leaf) continue;
|
|
78
|
+
const { languages, substitute, smartSubstitute } = descriptor.options;
|
|
79
|
+
const filledSet = priorFilled(prior, field);
|
|
80
|
+
const priorLeaf = singleLeaf(prior ?? {}, field);
|
|
81
|
+
const isUnchangedFill = (loc) => filledSet.has(loc) && priorLeaf?.[loc] !== void 0 && leaf[loc] === priorLeaf[loc];
|
|
82
|
+
const authored = {};
|
|
83
|
+
for (const [loc, val] of Object.entries(leaf)) {
|
|
84
|
+
if (typeof val === "string" && val !== "" && !isUnchangedFill(loc)) authored[loc] = val;
|
|
85
|
+
}
|
|
86
|
+
const filled = [];
|
|
87
|
+
for (const loc of languages) {
|
|
88
|
+
if (authored[loc] !== void 0) continue;
|
|
89
|
+
const sub = resolveI18nText(authored, loc, void 0, field, {
|
|
90
|
+
policy: "substitute",
|
|
91
|
+
substitute: substitute ?? ["any"],
|
|
92
|
+
...smartSubstitute ? { smartSubstitute } : {}
|
|
93
|
+
});
|
|
94
|
+
if (typeof sub === "string" && sub !== "") {
|
|
95
|
+
leaf[loc] = sub;
|
|
96
|
+
filled.push(loc);
|
|
97
|
+
} else if (isUnchangedFill(loc)) {
|
|
98
|
+
delete leaf[loc];
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if (filled.length > 0) {
|
|
102
|
+
marker ??= {};
|
|
103
|
+
marker[field] = filled;
|
|
104
|
+
} else if (marker) {
|
|
105
|
+
delete marker[field];
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (marker && Object.keys(marker).length > 0) {
|
|
109
|
+
record[MARKER] = marker;
|
|
110
|
+
} else {
|
|
111
|
+
delete record[MARKER];
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
39
115
|
// src/i18n/active.ts
|
|
40
116
|
function withI18n() {
|
|
41
117
|
return {
|
|
42
118
|
applyI18nLocale,
|
|
43
119
|
validateI18nTextValue,
|
|
44
120
|
enforceScript,
|
|
121
|
+
computeExemptFills,
|
|
122
|
+
densify,
|
|
45
123
|
buildDictionaryHandle(opts) {
|
|
46
124
|
return new DictionaryHandle(
|
|
47
125
|
opts.adapter,
|
|
@@ -85,6 +163,7 @@ export {
|
|
|
85
163
|
resolvePolicy,
|
|
86
164
|
setAtPathInPlace,
|
|
87
165
|
staticDict,
|
|
166
|
+
stripI18nFilled,
|
|
88
167
|
validateI18nTextValue,
|
|
89
168
|
withI18n
|
|
90
169
|
};
|
package/dist/i18n/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/i18n/active.ts"],"sourcesContent":["/**\n * Active i18n strategy — `withI18n()` returns the real implementation\n * that wires multi-locale resolution, i18nText validation, and the\n * `DictionaryHandle` for `dictKey` fields into the core read/write\n * paths.\n *\n * Consumers opt in by:\n *\n * ```ts\n * import { createNoydb } from '@noy-db/hub'\n * import { withI18n } from '@noy-db/hub/i18n'\n *\n * const db = await createNoydb({\n * store: ...,\n * user: ...,\n * i18nStrategy: withI18n(),\n * })\n * ```\n *\n * The factory delegates to the existing `core.ts` and `dictionary.ts`\n * modules. Splitting the import chain through this file is what lets\n * tsup tree-shake the `~854 LOC` of dictionary + locale resolution\n * out of the default bundle when no `withI18n()` import is present.\n *\n * @public\n */\n\nimport type { I18nStrategy, BuildDictionaryHandleOptions } from './strategy.js'\nimport { applyI18nLocale, validateI18nTextValue } from './core.js'\nimport { enforceScript } from './script.js'\nimport { DictionaryHandle } from './dictionary.js'\n\nexport function withI18n(): I18nStrategy {\n return {\n applyI18nLocale,\n validateI18nTextValue,\n enforceScript,\n buildDictionaryHandle<Keys extends string = string>(\n opts: BuildDictionaryHandleOptions<Keys>,\n ): DictionaryHandle<Keys> {\n return new DictionaryHandle<Keys>(\n opts.adapter,\n opts.compartmentName,\n opts.dictionaryName,\n opts.keyring,\n opts.getDEK,\n opts.encrypted,\n opts.ledger,\n opts.options,\n opts.findAndUpdateReferences,\n opts.emitter,\n )\n },\n }\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../src/i18n/densify.ts","../../src/i18n/active.ts"],"sourcesContent":["/**\n * #435 v1.x densifyOnWrite — eager-fill empty i18n slots from each field's\n * substitute chain at write time, recording provenance in the internal\n * `_i18nFilled` marker (decision A: dense map + prior-read).\n *\n * Pure functions over plain records; all DB wiring lives in collection.ts.\n * Only single-leaf i18n fields are supported (array-wildcard paths are\n * skipped, mirroring auto-translate).\n */\nimport { getAtPath, resolveI18nText } from './core.js'\nimport type { I18nTextDescriptor } from './core.js'\n\nconst MARKER = '_i18nFilled'\n\ntype Leaf = Record<string, string>\n\n/** Locales recorded as densify-filled on the prior record for `field`. */\nfunction priorFilled(prior: Record<string, unknown> | undefined, field: string): Set<string> {\n if (!prior) return new Set()\n const marker = prior[MARKER] as Record<string, string[]> | undefined\n return new Set(marker?.[field] ?? [])\n}\n\n/** The single leaf map for `field`, or undefined for absent / array-wildcard / non-object. */\nfunction singleLeaf(record: Record<string, unknown>, field: string): Leaf | undefined {\n const leaves = getAtPath(record, field)\n if (leaves.length !== 1) return undefined\n const leaf = leaves[0]\n if (!leaf || typeof leaf !== 'object' || Array.isArray(leaf)) return undefined\n return leaf as Leaf\n}\n\n/**\n * Per field, the locales that are UNCHANGED round-tripped densify fills — i.e.\n * marked filled on the prior record AND identical in the incoming record.\n * These are exempt from write-time script enforcement (they are derived copies,\n * not authored text). Slots the user changed are NOT exempt (validated as authored).\n */\nexport function computeExemptFills(\n prior: Record<string, unknown> | undefined,\n incoming: Record<string, unknown>,\n fields: Record<string, I18nTextDescriptor>,\n): Map<string, Set<string>> {\n const out = new Map<string, Set<string>>()\n if (!prior) return out\n for (const field of Object.keys(fields)) {\n const filled = priorFilled(prior, field)\n if (filled.size === 0) continue\n const priorLeaf = singleLeaf(prior, field)\n const incLeaf = singleLeaf(incoming, field)\n if (!priorLeaf || !incLeaf) continue\n const exempt = new Set<string>()\n for (const loc of filled) {\n if (incLeaf[loc] !== undefined && incLeaf[loc] !== '' && incLeaf[loc] === priorLeaf[loc]) {\n exempt.add(loc)\n }\n }\n if (exempt.size > 0) out.set(field, exempt)\n }\n return out\n}\n\n/**\n * Mutate `record` in place: fill empty declared-language slots for each\n * densify-enabled field from the field's substitute chain, recompute unchanged\n * prior fills, clear marks for slots that became authored, and write the\n * resulting `_i18nFilled` marker (removed when empty).\n *\n * `prior` is read-only — it is never mutated.\n *\n * Provenance uses value-equality (decision A): a slot counts as an unchanged\n * fill when it was prior-marked AND its value still equals the prior value. A\n * consequence is that re-authoring a value byte-identical to the existing fill\n * keeps it classified as a fill (the visible value is unchanged either way; the\n * slot stays script-exempt and will auto-refresh if its source later changes).\n * This is inherent to value-equality provenance, not a bug.\n */\nexport function densify(\n record: Record<string, unknown>,\n prior: Record<string, unknown> | undefined,\n fields: Record<string, I18nTextDescriptor>,\n): void {\n let marker = record[MARKER] as Record<string, string[]> | undefined\n\n for (const [field, descriptor] of Object.entries(fields)) {\n const leaf = singleLeaf(record, field)\n if (!leaf) continue\n const { languages, substitute, smartSubstitute } = descriptor.options\n const filledSet = priorFilled(prior, field)\n const priorLeaf = singleLeaf(prior ?? {}, field)\n const isUnchangedFill = (loc: string): boolean =>\n filledSet.has(loc) && priorLeaf?.[loc] !== undefined && leaf[loc] === priorLeaf[loc]\n\n // Authored source = present, non-empty, NOT an unchanged prior fill.\n const authored: Leaf = {}\n for (const [loc, val] of Object.entries(leaf)) {\n if (typeof val === 'string' && val !== '' && !isUnchangedFill(loc)) authored[loc] = val\n }\n\n const filled: string[] = []\n for (const loc of languages) {\n if (authored[loc] !== undefined) continue // real value present → not a fill\n const sub = resolveI18nText(authored, loc, undefined, field, {\n policy: 'substitute',\n substitute: substitute ?? ['any'],\n ...(smartSubstitute ? { smartSubstitute } : {}),\n })\n if (typeof sub === 'string' && sub !== '') {\n leaf[loc] = sub\n filled.push(loc)\n } else if (isUnchangedFill(loc)) {\n delete leaf[loc] // stale fill with no source left → drop it\n }\n }\n\n if (filled.length > 0) {\n marker ??= {}\n marker[field] = filled\n } else if (marker) {\n delete marker[field]\n }\n }\n\n if (marker && Object.keys(marker).length > 0) {\n record[MARKER] = marker\n } else {\n delete record[MARKER]\n }\n}\n","/**\n * Active i18n strategy — `withI18n()` returns the real implementation\n * that wires multi-locale resolution, i18nText validation, and the\n * `DictionaryHandle` for `dictKey` fields into the core read/write\n * paths.\n *\n * Consumers opt in by:\n *\n * ```ts\n * import { createNoydb } from '@noy-db/hub'\n * import { withI18n } from '@noy-db/hub/i18n'\n *\n * const db = await createNoydb({\n * store: ...,\n * user: ...,\n * i18nStrategy: withI18n(),\n * })\n * ```\n *\n * The factory delegates to the existing `core.ts` and `dictionary.ts`\n * modules. Splitting the import chain through this file is what lets\n * tsup tree-shake the `~854 LOC` of dictionary + locale resolution\n * out of the default bundle when no `withI18n()` import is present.\n *\n * @public\n */\n\nimport type { I18nStrategy, BuildDictionaryHandleOptions } from './strategy.js'\nimport { applyI18nLocale, validateI18nTextValue } from './core.js'\nimport { enforceScript } from './script.js'\nimport { computeExemptFills, densify } from './densify.js'\nimport { DictionaryHandle } from './dictionary.js'\n\nexport function withI18n(): I18nStrategy {\n return {\n applyI18nLocale,\n validateI18nTextValue,\n enforceScript,\n computeExemptFills,\n densify,\n buildDictionaryHandle<Keys extends string = string>(\n opts: BuildDictionaryHandleOptions<Keys>,\n ): DictionaryHandle<Keys> {\n return new DictionaryHandle<Keys>(\n opts.adapter,\n opts.compartmentName,\n opts.dictionaryName,\n opts.keyring,\n opts.getDEK,\n opts.encrypted,\n opts.ledger,\n opts.options,\n opts.findAndUpdateReferences,\n opts.emitter,\n )\n },\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAYA,IAAM,SAAS;AAKf,SAAS,YAAY,OAA4C,OAA4B;AAC3F,MAAI,CAAC,MAAO,QAAO,oBAAI,IAAI;AAC3B,QAAM,SAAS,MAAM,MAAM;AAC3B,SAAO,IAAI,IAAI,SAAS,KAAK,KAAK,CAAC,CAAC;AACtC;AAGA,SAAS,WAAW,QAAiC,OAAiC;AACpF,QAAM,SAAS,UAAU,QAAQ,KAAK;AACtC,MAAI,OAAO,WAAW,EAAG,QAAO;AAChC,QAAM,OAAO,OAAO,CAAC;AACrB,MAAI,CAAC,QAAQ,OAAO,SAAS,YAAY,MAAM,QAAQ,IAAI,EAAG,QAAO;AACrE,SAAO;AACT;AAQO,SAAS,mBACd,OACA,UACA,QAC0B;AAC1B,QAAM,MAAM,oBAAI,IAAyB;AACzC,MAAI,CAAC,MAAO,QAAO;AACnB,aAAW,SAAS,OAAO,KAAK,MAAM,GAAG;AACvC,UAAM,SAAS,YAAY,OAAO,KAAK;AACvC,QAAI,OAAO,SAAS,EAAG;AACvB,UAAM,YAAY,WAAW,OAAO,KAAK;AACzC,UAAM,UAAU,WAAW,UAAU,KAAK;AAC1C,QAAI,CAAC,aAAa,CAAC,QAAS;AAC5B,UAAM,SAAS,oBAAI,IAAY;AAC/B,eAAW,OAAO,QAAQ;AACxB,UAAI,QAAQ,GAAG,MAAM,UAAa,QAAQ,GAAG,MAAM,MAAM,QAAQ,GAAG,MAAM,UAAU,GAAG,GAAG;AACxF,eAAO,IAAI,GAAG;AAAA,MAChB;AAAA,IACF;AACA,QAAI,OAAO,OAAO,EAAG,KAAI,IAAI,OAAO,MAAM;AAAA,EAC5C;AACA,SAAO;AACT;AAiBO,SAAS,QACd,QACA,OACA,QACM;AACN,MAAI,SAAS,OAAO,MAAM;AAE1B,aAAW,CAAC,OAAO,UAAU,KAAK,OAAO,QAAQ,MAAM,GAAG;AACxD,UAAM,OAAO,WAAW,QAAQ,KAAK;AACrC,QAAI,CAAC,KAAM;AACX,UAAM,EAAE,WAAW,YAAY,gBAAgB,IAAI,WAAW;AAC9D,UAAM,YAAY,YAAY,OAAO,KAAK;AAC1C,UAAM,YAAY,WAAW,SAAS,CAAC,GAAG,KAAK;AAC/C,UAAM,kBAAkB,CAAC,QACvB,UAAU,IAAI,GAAG,KAAK,YAAY,GAAG,MAAM,UAAa,KAAK,GAAG,MAAM,UAAU,GAAG;AAGrF,UAAM,WAAiB,CAAC;AACxB,eAAW,CAAC,KAAK,GAAG,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC7C,UAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM,CAAC,gBAAgB,GAAG,EAAG,UAAS,GAAG,IAAI;AAAA,IACtF;AAEA,UAAM,SAAmB,CAAC;AAC1B,eAAW,OAAO,WAAW;AAC3B,UAAI,SAAS,GAAG,MAAM,OAAW;AACjC,YAAM,MAAM,gBAAgB,UAAU,KAAK,QAAW,OAAO;AAAA,QAC3D,QAAQ;AAAA,QACR,YAAY,cAAc,CAAC,KAAK;AAAA,QAChC,GAAI,kBAAkB,EAAE,gBAAgB,IAAI,CAAC;AAAA,MAC/C,CAAC;AACD,UAAI,OAAO,QAAQ,YAAY,QAAQ,IAAI;AACzC,aAAK,GAAG,IAAI;AACZ,eAAO,KAAK,GAAG;AAAA,MACjB,WAAW,gBAAgB,GAAG,GAAG;AAC/B,eAAO,KAAK,GAAG;AAAA,MACjB;AAAA,IACF;AAEA,QAAI,OAAO,SAAS,GAAG;AACrB,iBAAW,CAAC;AACZ,aAAO,KAAK,IAAI;AAAA,IAClB,WAAW,QAAQ;AACjB,aAAO,OAAO,KAAK;AAAA,IACrB;AAAA,EACF;AAEA,MAAI,UAAU,OAAO,KAAK,MAAM,EAAE,SAAS,GAAG;AAC5C,WAAO,MAAM,IAAI;AAAA,EACnB,OAAO;AACL,WAAO,OAAO,MAAM;AAAA,EACtB;AACF;;;AC/FO,SAAS,WAAyB;AACvC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,sBACE,MACwB;AACxB,aAAO,IAAI;AAAA,QACT,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,MACP;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import './predicate-BmhBSPCH.js';
|
|
2
|
-
import './strategy-
|
|
2
|
+
import './strategy-BoITAb2H.js';
|
|
3
3
|
import './ulid-DRH25k3y.js';
|
|
4
|
-
import './types-
|
|
4
|
+
import './types-84nsWSDF.js';
|
|
5
5
|
import './errors-Dwk2k1xY.js';
|
|
6
|
-
import './index-
|
|
6
|
+
import './index-DxBNV54L.js';
|
|
7
7
|
|
|
8
8
|
interface EncryptResult {
|
|
9
9
|
iv: string;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import './predicate-BmhBSPCH.cjs';
|
|
2
|
-
import './strategy-
|
|
2
|
+
import './strategy-DDNvt_UD.cjs';
|
|
3
3
|
import './ulid-DRH25k3y.cjs';
|
|
4
|
-
import './types-
|
|
4
|
+
import './types-B_eCkuEI.cjs';
|
|
5
5
|
import './errors-Dwk2k1xY.cjs';
|
|
6
|
-
import './index-
|
|
6
|
+
import './index-CVnt2Qmq.cjs';
|
|
7
7
|
|
|
8
8
|
interface EncryptResult {
|
|
9
9
|
iv: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { C as CollectionIndexes, a as Clause, O as Operator } from './predicate-BmhBSPCH.cjs';
|
|
2
2
|
import { N as NoydbError } from './errors-Dwk2k1xY.cjs';
|
|
3
|
-
import { a as I18nTextDescriptor,
|
|
3
|
+
import { a as I18nTextDescriptor, P as MoneyDescriptor, A as AggregateStrategy, k as AggregateSpec, l as Aggregation, j as AggregateResult, p as GroupedQuery, q as GroupedQueryN } from './strategy-DDNvt_UD.cjs';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Foreign-key references — the soft-FK mechanism.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { C as CollectionIndexes, a as Clause, O as Operator } from './predicate-BmhBSPCH.js';
|
|
2
2
|
import { N as NoydbError } from './errors-Dwk2k1xY.js';
|
|
3
|
-
import { a as I18nTextDescriptor,
|
|
3
|
+
import { a as I18nTextDescriptor, P as MoneyDescriptor, A as AggregateStrategy, k as AggregateSpec, l as Aggregation, j as AggregateResult, p as GroupedQuery, q as GroupedQueryN } from './strategy-BoITAb2H.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Foreign-key references — the soft-FK mechanism.
|
package/dist/index.cjs
CHANGED
|
@@ -7578,13 +7578,14 @@ function stripDisallowed(str, scripts) {
|
|
|
7578
7578
|
for (const ch of str) if (ok.test(ch)) out += ch;
|
|
7579
7579
|
return out;
|
|
7580
7580
|
}
|
|
7581
|
-
function enforceScript(value, field, descriptor) {
|
|
7581
|
+
function enforceScript(value, field, descriptor, exempt) {
|
|
7582
7582
|
const opt = descriptor.options;
|
|
7583
7583
|
if (!opt.script) return { value, warnings: [] };
|
|
7584
7584
|
const mode = opt.onScriptViolation ?? "reject";
|
|
7585
7585
|
const warnings = [];
|
|
7586
7586
|
let out = value;
|
|
7587
7587
|
for (const [locale, raw] of Object.entries(value)) {
|
|
7588
|
+
if (exempt?.has(locale)) continue;
|
|
7588
7589
|
if (typeof raw !== "string") continue;
|
|
7589
7590
|
const allowed = allowedFor(descriptor, locale);
|
|
7590
7591
|
if (fullMatcher(allowed).test(raw)) continue;
|
|
@@ -7675,8 +7676,18 @@ var init_script = __esm({
|
|
|
7675
7676
|
|
|
7676
7677
|
// src/i18n/core.ts
|
|
7677
7678
|
function i18nText(options) {
|
|
7679
|
+
if (options.densifyOnWrite === true && hasThrowPolicy(options.onMissing)) {
|
|
7680
|
+
throw new Error(
|
|
7681
|
+
`i18nText: densifyOnWrite cannot be combined with an explicit onMissing 'throw' policy \u2014 densify fills every empty slot, so a 'throw' would be unreachable. Remove the 'throw' policy or disable densifyOnWrite.`
|
|
7682
|
+
);
|
|
7683
|
+
}
|
|
7678
7684
|
return { _noydbI18nText: true, options };
|
|
7679
7685
|
}
|
|
7686
|
+
function hasThrowPolicy(onMissing) {
|
|
7687
|
+
if (onMissing === void 0) return false;
|
|
7688
|
+
if (typeof onMissing === "string") return onMissing === "throw";
|
|
7689
|
+
return Object.values(onMissing).includes("throw");
|
|
7690
|
+
}
|
|
7680
7691
|
function isI18nTextDescriptor(x) {
|
|
7681
7692
|
return typeof x === "object" && x !== null && x._noydbI18nText === true;
|
|
7682
7693
|
}
|
|
@@ -7874,8 +7885,15 @@ function applyI18nLocale(record, i18nFields, locale, fallback, layer = "read") {
|
|
|
7874
7885
|
};
|
|
7875
7886
|
result = applyAtPath(result, field, locale, fallback, opts);
|
|
7876
7887
|
}
|
|
7888
|
+
result = stripI18nFilled(result);
|
|
7877
7889
|
return result;
|
|
7878
7890
|
}
|
|
7891
|
+
function stripI18nFilled(record) {
|
|
7892
|
+
if (!Object.prototype.hasOwnProperty.call(record, "_i18nFilled")) return record;
|
|
7893
|
+
const rest = { ...record };
|
|
7894
|
+
delete rest._i18nFilled;
|
|
7895
|
+
return rest;
|
|
7896
|
+
}
|
|
7879
7897
|
var init_core = __esm({
|
|
7880
7898
|
"src/i18n/core.ts"() {
|
|
7881
7899
|
"use strict";
|
|
@@ -8905,6 +8923,11 @@ var init_strategy2 = __esm({
|
|
|
8905
8923
|
enforceScript(value) {
|
|
8906
8924
|
return { value, warnings: [] };
|
|
8907
8925
|
},
|
|
8926
|
+
computeExemptFills() {
|
|
8927
|
+
return /* @__PURE__ */ new Map();
|
|
8928
|
+
},
|
|
8929
|
+
densify() {
|
|
8930
|
+
},
|
|
8908
8931
|
buildDictionaryHandle() {
|
|
8909
8932
|
throw notEnabled("vault.dictionary()");
|
|
8910
8933
|
}
|
|
@@ -13868,6 +13891,12 @@ var init_collection = __esm({
|
|
|
13868
13891
|
* Declared via the `i18nFields` collection option.
|
|
13869
13892
|
*/
|
|
13870
13893
|
i18nFields;
|
|
13894
|
+
/**
|
|
13895
|
+
* #435 — the densify-enabled subset of {@link i18nFields} (fields whose
|
|
13896
|
+
* descriptor opts in via `densifyOnWrite: true`). `undefined` when none opt
|
|
13897
|
+
* in, so the write path skips all densify work for ordinary collections.
|
|
13898
|
+
*/
|
|
13899
|
+
i18nDensifyFields;
|
|
13871
13900
|
/**
|
|
13872
13901
|
* Map of field name → `DictKeyDescriptor` for fields declared with
|
|
13873
13902
|
* `dictKey()`. Used by `get()`/`list()` to add `<field>Label` virtual
|
|
@@ -14054,6 +14083,10 @@ var init_collection = __esm({
|
|
|
14054
14083
|
this.refEnforcer = opts.refEnforcer;
|
|
14055
14084
|
this.joinResolver = opts.joinResolver;
|
|
14056
14085
|
this.i18nFields = opts.i18nFields;
|
|
14086
|
+
const densifyFields = opts.i18nFields ? Object.fromEntries(
|
|
14087
|
+
Object.entries(opts.i18nFields).filter(([, d]) => d.options.densifyOnWrite === true)
|
|
14088
|
+
) : {};
|
|
14089
|
+
this.i18nDensifyFields = Object.keys(densifyFields).length > 0 ? densifyFields : void 0;
|
|
14057
14090
|
this.dictKeyFields = opts.dictKeyFields;
|
|
14058
14091
|
if (opts.moneyFields) validateMoneyFieldPaths(opts.moneyFields);
|
|
14059
14092
|
this.moneyFields = opts.moneyFields;
|
|
@@ -14373,6 +14406,32 @@ var init_collection = __esm({
|
|
|
14373
14406
|
if (busAfterPut) await this.subsystemBus.dispatch("afterPut", event);
|
|
14374
14407
|
}
|
|
14375
14408
|
}
|
|
14409
|
+
/**
|
|
14410
|
+
* #435 — resolve the prior stored record (with its `_i18nFilled` marker) for
|
|
14411
|
+
* densify. Eager: in-memory cache; lazy: LRU then adapter. undefined if absent.
|
|
14412
|
+
*/
|
|
14413
|
+
async resolveDensifyPrior(id) {
|
|
14414
|
+
if (this.lazy && this.lru) {
|
|
14415
|
+
const cached = this.lru.get(id);
|
|
14416
|
+
if (cached) return cached.record;
|
|
14417
|
+
const env = await this.adapter.get(this.vault, this.name, id);
|
|
14418
|
+
if (!env) return void 0;
|
|
14419
|
+
const rec = await this.decryptRecord(env);
|
|
14420
|
+
return rec === null ? void 0 : rec;
|
|
14421
|
+
}
|
|
14422
|
+
await this.ensureHydrated();
|
|
14423
|
+
return this.cache.get(id)?.record;
|
|
14424
|
+
}
|
|
14425
|
+
/**
|
|
14426
|
+
* #435 — densify provenance for a record: which i18n slots were auto-filled,
|
|
14427
|
+
* e.g. `{ name: ['en'] }`. undefined when nothing was filled. The marker is
|
|
14428
|
+
* stripped from ordinary reads; this is the sanctioned audit accessor.
|
|
14429
|
+
*/
|
|
14430
|
+
async i18nProvenance(id) {
|
|
14431
|
+
const prior = await this.resolveDensifyPrior(id);
|
|
14432
|
+
const marker = prior?.["_i18nFilled"];
|
|
14433
|
+
return marker && Object.keys(marker).length > 0 ? marker : void 0;
|
|
14434
|
+
}
|
|
14376
14435
|
/**
|
|
14377
14436
|
* Validate a record against this collection's schema WITHOUT writing it.
|
|
14378
14437
|
* Returns the (possibly coerced) record on success; throws
|
|
@@ -14487,6 +14546,16 @@ var init_collection = __esm({
|
|
|
14487
14546
|
setAtPathInPlace(obj, field, translated);
|
|
14488
14547
|
}
|
|
14489
14548
|
}
|
|
14549
|
+
let densifyPrior;
|
|
14550
|
+
let exemptFills;
|
|
14551
|
+
if (this.i18nDensifyFields) {
|
|
14552
|
+
densifyPrior = await this.resolveDensifyPrior(id);
|
|
14553
|
+
exemptFills = this.i18nStrategy.computeExemptFills(
|
|
14554
|
+
densifyPrior,
|
|
14555
|
+
record,
|
|
14556
|
+
this.i18nDensifyFields
|
|
14557
|
+
);
|
|
14558
|
+
}
|
|
14490
14559
|
if (this.i18nFields) {
|
|
14491
14560
|
const obj = record;
|
|
14492
14561
|
for (const [field, descriptor] of Object.entries(this.i18nFields)) {
|
|
@@ -14494,18 +14563,38 @@ var init_collection = __esm({
|
|
|
14494
14563
|
for (const leaf of getAtPath(obj, field)) {
|
|
14495
14564
|
if (!leaf || typeof leaf !== "object" || Array.isArray(leaf)) continue;
|
|
14496
14565
|
const leafMap = leaf;
|
|
14497
|
-
const { value: cleaned } = this.i18nStrategy.enforceScript(
|
|
14566
|
+
const { value: cleaned, warnings } = this.i18nStrategy.enforceScript(
|
|
14498
14567
|
leafMap,
|
|
14499
14568
|
field,
|
|
14500
|
-
descriptor
|
|
14569
|
+
descriptor,
|
|
14570
|
+
exemptFills?.get(field)
|
|
14501
14571
|
);
|
|
14502
14572
|
if (cleaned !== leafMap) Object.assign(leafMap, cleaned);
|
|
14573
|
+
const mode = descriptor.options.onScriptViolation;
|
|
14574
|
+
if (mode === "warn" || mode === "filter") {
|
|
14575
|
+
for (const w of warnings) {
|
|
14576
|
+
this.emitter.emit("i18n:script-violation", {
|
|
14577
|
+
vault: this.vault,
|
|
14578
|
+
collection: this.name,
|
|
14579
|
+
id,
|
|
14580
|
+
mode,
|
|
14581
|
+
warning: w
|
|
14582
|
+
});
|
|
14583
|
+
}
|
|
14584
|
+
}
|
|
14503
14585
|
}
|
|
14504
14586
|
}
|
|
14505
14587
|
}
|
|
14506
14588
|
if (this.i18nPutValidator !== void 0) {
|
|
14507
14589
|
this.i18nPutValidator(record);
|
|
14508
14590
|
}
|
|
14591
|
+
if (this.i18nDensifyFields) {
|
|
14592
|
+
this.i18nStrategy.densify(
|
|
14593
|
+
record,
|
|
14594
|
+
densifyPrior,
|
|
14595
|
+
this.i18nDensifyFields
|
|
14596
|
+
);
|
|
14597
|
+
}
|
|
14509
14598
|
if (this.refEnforcer !== void 0) {
|
|
14510
14599
|
await this.refEnforcer.enforceRefsOnPut(this.name, record);
|
|
14511
14600
|
}
|
|
@@ -15359,7 +15448,7 @@ var init_collection = __esm({
|
|
|
15359
15448
|
}
|
|
15360
15449
|
await this.ensureHydrated();
|
|
15361
15450
|
const entries = [];
|
|
15362
|
-
for (const [id, e] of this.cache) entries.push({ id, record: e.record });
|
|
15451
|
+
for (const [id, e] of this.cache) entries.push({ id, record: stripI18nFilled(e.record) });
|
|
15363
15452
|
return searchScan(entries, field, query, opts);
|
|
15364
15453
|
}
|
|
15365
15454
|
// ─── Bulk operations ─────────────────────────────────────
|
|
@@ -16273,7 +16362,7 @@ var init_collection = __esm({
|
|
|
16273
16362
|
const hasStaticDisplay = hasDict && this.dictKeyFields !== void 0 && Object.values(this.dictKeyFields).some(
|
|
16274
16363
|
(d) => isStaticDictDescriptor(d) && d.displayLocale !== void 0
|
|
16275
16364
|
);
|
|
16276
|
-
if (!locale && !hasStaticDisplay) return result;
|
|
16365
|
+
if (!locale && !hasStaticDisplay) return stripI18nFilled(result);
|
|
16277
16366
|
const layer = localeOpts?._layer ?? "read";
|
|
16278
16367
|
if (locale && hasI18n && this.i18nFields) {
|
|
16279
16368
|
result = this.i18nStrategy.applyI18nLocale(result, this.i18nFields, locale, localeOpts?.fallback, layer);
|
|
@@ -16340,7 +16429,7 @@ var init_collection = __esm({
|
|
|
16340
16429
|
}
|
|
16341
16430
|
result = withLabels;
|
|
16342
16431
|
}
|
|
16343
|
-
return result;
|
|
16432
|
+
return stripI18nFilled(result);
|
|
16344
16433
|
}
|
|
16345
16434
|
/**
|
|
16346
16435
|
* Low-level: encrypt a pre-serialised JSON string into an EncryptedEnvelope.
|