superbee 0.4.3-pre.20 → 0.4.3-pre.22
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/publication-bridge.mjs +695 -325
- package/dist/publication.mjs +667 -326
- package/dist/superbee.mjs +8615 -5900
- package/package.json +1 -1
|
@@ -920,25 +920,25 @@ var require_pairs = __commonJS({
|
|
|
920
920
|
var _toString = Object.prototype.toString;
|
|
921
921
|
function resolveYamlPairs(data) {
|
|
922
922
|
if (data === null) return true;
|
|
923
|
-
var index, length, pair,
|
|
923
|
+
var index, length, pair, keys2, result, object = data;
|
|
924
924
|
result = new Array(object.length);
|
|
925
925
|
for (index = 0, length = object.length; index < length; index += 1) {
|
|
926
926
|
pair = object[index];
|
|
927
927
|
if (_toString.call(pair) !== "[object Object]") return false;
|
|
928
|
-
|
|
929
|
-
if (
|
|
930
|
-
result[index] = [
|
|
928
|
+
keys2 = Object.keys(pair);
|
|
929
|
+
if (keys2.length !== 1) return false;
|
|
930
|
+
result[index] = [keys2[0], pair[keys2[0]]];
|
|
931
931
|
}
|
|
932
932
|
return true;
|
|
933
933
|
}
|
|
934
934
|
function constructYamlPairs(data) {
|
|
935
935
|
if (data === null) return [];
|
|
936
|
-
var index, length, pair,
|
|
936
|
+
var index, length, pair, keys2, result, object = data;
|
|
937
937
|
result = new Array(object.length);
|
|
938
938
|
for (index = 0, length = object.length; index < length; index += 1) {
|
|
939
939
|
pair = object[index];
|
|
940
|
-
|
|
941
|
-
result[index] = [
|
|
940
|
+
keys2 = Object.keys(pair);
|
|
941
|
+
result[index] = [keys2[0], pair[keys2[0]]];
|
|
942
942
|
}
|
|
943
943
|
return result;
|
|
944
944
|
}
|
|
@@ -2345,12 +2345,12 @@ var require_dumper = __commonJS({
|
|
|
2345
2345
|
"OFF"
|
|
2346
2346
|
];
|
|
2347
2347
|
function compileStyleMap(schema, map) {
|
|
2348
|
-
var result,
|
|
2348
|
+
var result, keys2, index, length, tag, style, type;
|
|
2349
2349
|
if (map === null) return {};
|
|
2350
2350
|
result = {};
|
|
2351
|
-
|
|
2352
|
-
for (index = 0, length =
|
|
2353
|
-
tag =
|
|
2351
|
+
keys2 = Object.keys(map);
|
|
2352
|
+
for (index = 0, length = keys2.length; index < length; index += 1) {
|
|
2353
|
+
tag = keys2[index];
|
|
2354
2354
|
style = String(map[tag]);
|
|
2355
2355
|
if (tag.slice(0, 2) === "!!") {
|
|
2356
2356
|
tag = "tag:yaml.org,2002:" + tag.slice(2);
|
|
@@ -2874,7 +2874,38 @@ import { createHash as createHash3 } from "node:crypto";
|
|
|
2874
2874
|
// ../core/src/backend.ts
|
|
2875
2875
|
import path3 from "node:path";
|
|
2876
2876
|
|
|
2877
|
-
// ../core/src/
|
|
2877
|
+
// ../core/src/errors.ts
|
|
2878
|
+
var InvalidInputError = class extends Error {
|
|
2879
|
+
constructor(message) {
|
|
2880
|
+
super(message);
|
|
2881
|
+
this.name = "InvalidInputError";
|
|
2882
|
+
}
|
|
2883
|
+
};
|
|
2884
|
+
var FilesystemIdentityAliasError = class extends InvalidInputError {
|
|
2885
|
+
rel;
|
|
2886
|
+
segment;
|
|
2887
|
+
constructor(rel, segment) {
|
|
2888
|
+
super(
|
|
2889
|
+
`Path '${rel}' does not match the exact spelling of an existing filesystem entry at segment '${segment}'; ids that differ only by case or Unicode normalization cannot share one file.`
|
|
2890
|
+
);
|
|
2891
|
+
this.name = "FilesystemIdentityAliasError";
|
|
2892
|
+
this.rel = rel;
|
|
2893
|
+
this.segment = segment;
|
|
2894
|
+
}
|
|
2895
|
+
};
|
|
2896
|
+
var ConcurrentReplacementError = class extends Error {
|
|
2897
|
+
rel;
|
|
2898
|
+
/** Optional bounded backoff hint for a transient host condition; ordinary observation races use zero. */
|
|
2899
|
+
retryAfterMs;
|
|
2900
|
+
constructor(rel, attempts, retryAfterMs = 0) {
|
|
2901
|
+
super(`Path '${rel}' could not be bound to one stable entry during ${attempts} filesystem attempt(s); retry.`);
|
|
2902
|
+
this.name = "ConcurrentReplacementError";
|
|
2903
|
+
this.rel = rel;
|
|
2904
|
+
this.retryAfterMs = retryAfterMs;
|
|
2905
|
+
}
|
|
2906
|
+
};
|
|
2907
|
+
|
|
2908
|
+
// ../core/src/portable-frontmatter.ts
|
|
2878
2909
|
var import_js_yaml = __toESM(require_js_yaml2(), 1);
|
|
2879
2910
|
|
|
2880
2911
|
// ../core/src/frontmatter-contract.ts
|
|
@@ -2922,111 +2953,22 @@ function splitLeadingFrontmatter(raw, context) {
|
|
|
2922
2953
|
throw new MalformedDocumentError(context, new Error("unterminated YAML frontmatter delimiter"));
|
|
2923
2954
|
}
|
|
2924
2955
|
|
|
2925
|
-
// ../core/src/frontmatter.ts
|
|
2926
|
-
|
|
2927
|
-
function requireYamlTimestampType() {
|
|
2928
|
-
const type = import_js_yaml.default.DEFAULT_SAFE_SCHEMA.implicit.find(
|
|
2929
|
-
(candidate) => candidate.tag === YAML_TIMESTAMP_TAG
|
|
2930
|
-
);
|
|
2931
|
-
if (!type) throw new Error("js-yaml safe schema is missing its timestamp type");
|
|
2932
|
-
return type;
|
|
2933
|
-
}
|
|
2934
|
-
var yamlTimestampType = requireYamlTimestampType();
|
|
2935
|
-
var stringTimestampType = new import_js_yaml.default.Type(YAML_TIMESTAMP_TAG, {
|
|
2936
|
-
kind: "scalar",
|
|
2937
|
-
resolve: (value) => yamlTimestampType.resolve(value),
|
|
2938
|
-
construct: (value) => value
|
|
2939
|
-
});
|
|
2940
|
-
var losslessDateSchema = new import_js_yaml.default.Schema({
|
|
2941
|
-
include: [import_js_yaml.default.DEFAULT_SAFE_SCHEMA],
|
|
2942
|
-
implicit: [stringTimestampType]
|
|
2943
|
-
});
|
|
2944
|
-
var yamlEngine = {
|
|
2945
|
-
parse(input) {
|
|
2946
|
-
return import_js_yaml.default.safeLoad(input, { schema: losslessDateSchema }) ?? {};
|
|
2947
|
-
}
|
|
2948
|
-
};
|
|
2949
|
-
function normalizeFrontmatter(data, okfVersion) {
|
|
2950
|
-
const out = { ...data };
|
|
2951
|
-
if (okfVersion === "0.2") return out;
|
|
2952
|
-
const value = out.timestamp;
|
|
2953
|
-
if (value instanceof Date) {
|
|
2954
|
-
out.timestamp = value.toISOString();
|
|
2955
|
-
} else if (typeof value === "number" && Number.isFinite(value)) {
|
|
2956
|
-
out.timestamp = new Date(value).toISOString();
|
|
2957
|
-
} else if (typeof value === "string" && yamlTimestampType.resolve(value)) {
|
|
2958
|
-
const parsed = yamlTimestampType.construct(value);
|
|
2959
|
-
if (parsed instanceof Date) out.timestamp = parsed.toISOString();
|
|
2960
|
-
}
|
|
2961
|
-
return out;
|
|
2962
|
-
}
|
|
2963
|
-
function parseMarkdown(raw, context, options = {}) {
|
|
2956
|
+
// ../core/src/portable-frontmatter.ts
|
|
2957
|
+
function parseLeadingFrontmatter(raw, context) {
|
|
2964
2958
|
const split = splitLeadingFrontmatter(raw, context);
|
|
2965
|
-
if (!("yamlSource" in split)) return {
|
|
2966
|
-
return { frontmatter: parseFrontmatter(split.yamlSource, context, options), body: split.body };
|
|
2967
|
-
}
|
|
2968
|
-
function parseFrontmatter(source, context, options = {}) {
|
|
2969
|
-
let parsed;
|
|
2959
|
+
if (!("yamlSource" in split)) return {};
|
|
2970
2960
|
try {
|
|
2971
|
-
parsed =
|
|
2972
|
-
|
|
2973
|
-
|
|
2961
|
+
const parsed = import_js_yaml.default.safeLoad(split.yamlSource);
|
|
2962
|
+
if (parsed === void 0 || parsed === null) return {};
|
|
2963
|
+
if (typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
2964
|
+
throw new TypeError("YAML frontmatter must be a mapping");
|
|
2965
|
+
}
|
|
2966
|
+
return parsed;
|
|
2967
|
+
} catch (error) {
|
|
2968
|
+
if (error instanceof MalformedDocumentError) throw error;
|
|
2969
|
+
throw new MalformedDocumentError(context, error);
|
|
2974
2970
|
}
|
|
2975
|
-
return normalizeFrontmatter(parsed, options.okfVersion);
|
|
2976
|
-
}
|
|
2977
|
-
function stringifyFrontmatter(data) {
|
|
2978
|
-
return import_js_yaml.default.safeDump(data).trim();
|
|
2979
2971
|
}
|
|
2980
|
-
function normalizeDocumentBodyForStorage(body) {
|
|
2981
|
-
return body.endsWith("\n") ? body : `${body}
|
|
2982
|
-
`;
|
|
2983
|
-
}
|
|
2984
|
-
function stringifyWithData(data, body) {
|
|
2985
|
-
return stringifyWithSerializedFrontmatter(stringifyFrontmatter(data), body);
|
|
2986
|
-
}
|
|
2987
|
-
function stringifyWithSerializedFrontmatter(dumped, body) {
|
|
2988
|
-
const content = body ?? "";
|
|
2989
|
-
const newline = (value) => value.endsWith("\n") ? value : `${value}
|
|
2990
|
-
`;
|
|
2991
|
-
if (dumped === "{}") return normalizeDocumentBodyForStorage(content);
|
|
2992
|
-
return `---
|
|
2993
|
-
${newline(dumped)}---
|
|
2994
|
-
${normalizeDocumentBodyForStorage(content)}`;
|
|
2995
|
-
}
|
|
2996
|
-
function stringifyDoc(frontmatter2, body) {
|
|
2997
|
-
return stringifyWithData(frontmatter2, body);
|
|
2998
|
-
}
|
|
2999
|
-
|
|
3000
|
-
// ../core/src/errors.ts
|
|
3001
|
-
var InvalidInputError = class extends Error {
|
|
3002
|
-
constructor(message) {
|
|
3003
|
-
super(message);
|
|
3004
|
-
this.name = "InvalidInputError";
|
|
3005
|
-
}
|
|
3006
|
-
};
|
|
3007
|
-
var FilesystemIdentityAliasError = class extends InvalidInputError {
|
|
3008
|
-
rel;
|
|
3009
|
-
segment;
|
|
3010
|
-
constructor(rel, segment) {
|
|
3011
|
-
super(
|
|
3012
|
-
`Path '${rel}' does not match the exact spelling of an existing filesystem entry at segment '${segment}'; ids that differ only by case or Unicode normalization cannot share one file.`
|
|
3013
|
-
);
|
|
3014
|
-
this.name = "FilesystemIdentityAliasError";
|
|
3015
|
-
this.rel = rel;
|
|
3016
|
-
this.segment = segment;
|
|
3017
|
-
}
|
|
3018
|
-
};
|
|
3019
|
-
var ConcurrentReplacementError = class extends Error {
|
|
3020
|
-
rel;
|
|
3021
|
-
/** Optional bounded backoff hint for a transient host condition; ordinary observation races use zero. */
|
|
3022
|
-
retryAfterMs;
|
|
3023
|
-
constructor(rel, attempts, retryAfterMs = 0) {
|
|
3024
|
-
super(`Path '${rel}' could not be bound to one stable entry during ${attempts} filesystem attempt(s); retry.`);
|
|
3025
|
-
this.name = "ConcurrentReplacementError";
|
|
3026
|
-
this.rel = rel;
|
|
3027
|
-
this.retryAfterMs = retryAfterMs;
|
|
3028
|
-
}
|
|
3029
|
-
};
|
|
3030
2972
|
|
|
3031
2973
|
// ../core/src/paths.ts
|
|
3032
2974
|
var RESERVED_FILENAMES = ["index.md", "log.md"];
|
|
@@ -3097,11 +3039,362 @@ function assertSafeBlobKey(key) {
|
|
|
3097
3039
|
);
|
|
3098
3040
|
}
|
|
3099
3041
|
}
|
|
3100
|
-
function assertSafeReservedDir(dir) {
|
|
3101
|
-
if (typeof dir !== "string") {
|
|
3102
|
-
throw new InvalidInputError("Reserved-file directory must be a string.");
|
|
3103
|
-
}
|
|
3104
|
-
if (dir !== "") assertPortablePath(dir, "Reserved-file directory");
|
|
3042
|
+
function assertSafeReservedDir(dir) {
|
|
3043
|
+
if (typeof dir !== "string") {
|
|
3044
|
+
throw new InvalidInputError("Reserved-file directory must be a string.");
|
|
3045
|
+
}
|
|
3046
|
+
if (dir !== "") assertPortablePath(dir, "Reserved-file directory");
|
|
3047
|
+
}
|
|
3048
|
+
|
|
3049
|
+
// ../core/src/sha256.ts
|
|
3050
|
+
var K = new Uint32Array([
|
|
3051
|
+
1116352408,
|
|
3052
|
+
1899447441,
|
|
3053
|
+
3049323471,
|
|
3054
|
+
3921009573,
|
|
3055
|
+
961987163,
|
|
3056
|
+
1508970993,
|
|
3057
|
+
2453635748,
|
|
3058
|
+
2870763221,
|
|
3059
|
+
3624381080,
|
|
3060
|
+
310598401,
|
|
3061
|
+
607225278,
|
|
3062
|
+
1426881987,
|
|
3063
|
+
1925078388,
|
|
3064
|
+
2162078206,
|
|
3065
|
+
2614888103,
|
|
3066
|
+
3248222580,
|
|
3067
|
+
3835390401,
|
|
3068
|
+
4022224774,
|
|
3069
|
+
264347078,
|
|
3070
|
+
604807628,
|
|
3071
|
+
770255983,
|
|
3072
|
+
1249150122,
|
|
3073
|
+
1555081692,
|
|
3074
|
+
1996064986,
|
|
3075
|
+
2554220882,
|
|
3076
|
+
2821834349,
|
|
3077
|
+
2952996808,
|
|
3078
|
+
3210313671,
|
|
3079
|
+
3336571891,
|
|
3080
|
+
3584528711,
|
|
3081
|
+
113926993,
|
|
3082
|
+
338241895,
|
|
3083
|
+
666307205,
|
|
3084
|
+
773529912,
|
|
3085
|
+
1294757372,
|
|
3086
|
+
1396182291,
|
|
3087
|
+
1695183700,
|
|
3088
|
+
1986661051,
|
|
3089
|
+
2177026350,
|
|
3090
|
+
2456956037,
|
|
3091
|
+
2730485921,
|
|
3092
|
+
2820302411,
|
|
3093
|
+
3259730800,
|
|
3094
|
+
3345764771,
|
|
3095
|
+
3516065817,
|
|
3096
|
+
3600352804,
|
|
3097
|
+
4094571909,
|
|
3098
|
+
275423344,
|
|
3099
|
+
430227734,
|
|
3100
|
+
506948616,
|
|
3101
|
+
659060556,
|
|
3102
|
+
883997877,
|
|
3103
|
+
958139571,
|
|
3104
|
+
1322822218,
|
|
3105
|
+
1537002063,
|
|
3106
|
+
1747873779,
|
|
3107
|
+
1955562222,
|
|
3108
|
+
2024104815,
|
|
3109
|
+
2227730452,
|
|
3110
|
+
2361852424,
|
|
3111
|
+
2428436474,
|
|
3112
|
+
2756734187,
|
|
3113
|
+
3204031479,
|
|
3114
|
+
3329325298
|
|
3115
|
+
]);
|
|
3116
|
+
var INITIAL_STATE = new Uint32Array([
|
|
3117
|
+
1779033703,
|
|
3118
|
+
3144134277,
|
|
3119
|
+
1013904242,
|
|
3120
|
+
2773480762,
|
|
3121
|
+
1359893119,
|
|
3122
|
+
2600822924,
|
|
3123
|
+
528734635,
|
|
3124
|
+
1541459225
|
|
3125
|
+
]);
|
|
3126
|
+
var encoder = new TextEncoder();
|
|
3127
|
+
function rotr(value, bits) {
|
|
3128
|
+
return value >>> bits | value << 32 - bits;
|
|
3129
|
+
}
|
|
3130
|
+
function compress(h, w, view, offset) {
|
|
3131
|
+
for (let i = 0; i < 16; i++) {
|
|
3132
|
+
w[i] = view.getUint32(offset + i * 4);
|
|
3133
|
+
}
|
|
3134
|
+
for (let i = 16; i < 64; i++) {
|
|
3135
|
+
const w15 = w[i - 15];
|
|
3136
|
+
const w2 = w[i - 2];
|
|
3137
|
+
const s0 = rotr(w15, 7) ^ rotr(w15, 18) ^ w15 >>> 3;
|
|
3138
|
+
const s1 = rotr(w2, 17) ^ rotr(w2, 19) ^ w2 >>> 10;
|
|
3139
|
+
w[i] = w[i - 16] + s0 + w[i - 7] + s1 >>> 0;
|
|
3140
|
+
}
|
|
3141
|
+
let a = h[0];
|
|
3142
|
+
let b = h[1];
|
|
3143
|
+
let c = h[2];
|
|
3144
|
+
let d = h[3];
|
|
3145
|
+
let e = h[4];
|
|
3146
|
+
let f = h[5];
|
|
3147
|
+
let g = h[6];
|
|
3148
|
+
let hh = h[7];
|
|
3149
|
+
for (let i = 0; i < 64; i++) {
|
|
3150
|
+
const S1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25);
|
|
3151
|
+
const ch = e & f ^ ~e & g;
|
|
3152
|
+
const t1 = hh + S1 + ch + K[i] + w[i] >>> 0;
|
|
3153
|
+
const S0 = rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22);
|
|
3154
|
+
const maj = a & b ^ a & c ^ b & c;
|
|
3155
|
+
const t2 = S0 + maj >>> 0;
|
|
3156
|
+
hh = g;
|
|
3157
|
+
g = f;
|
|
3158
|
+
f = e;
|
|
3159
|
+
e = d + t1 >>> 0;
|
|
3160
|
+
d = c;
|
|
3161
|
+
c = b;
|
|
3162
|
+
b = a;
|
|
3163
|
+
a = t1 + t2 >>> 0;
|
|
3164
|
+
}
|
|
3165
|
+
h[0] = h[0] + a >>> 0;
|
|
3166
|
+
h[1] = h[1] + b >>> 0;
|
|
3167
|
+
h[2] = h[2] + c >>> 0;
|
|
3168
|
+
h[3] = h[3] + d >>> 0;
|
|
3169
|
+
h[4] = h[4] + e >>> 0;
|
|
3170
|
+
h[5] = h[5] + f >>> 0;
|
|
3171
|
+
h[6] = h[6] + g >>> 0;
|
|
3172
|
+
h[7] = h[7] + hh >>> 0;
|
|
3173
|
+
}
|
|
3174
|
+
function sha256HexOfBytes(bytes) {
|
|
3175
|
+
const h = new Uint32Array(INITIAL_STATE);
|
|
3176
|
+
const w = new Uint32Array(64);
|
|
3177
|
+
const length = bytes.byteLength;
|
|
3178
|
+
const view = new DataView(bytes.buffer, bytes.byteOffset, length);
|
|
3179
|
+
const fullBlocks = length >>> 6;
|
|
3180
|
+
for (let block = 0; block < fullBlocks; block++) {
|
|
3181
|
+
compress(h, w, view, block * 64);
|
|
3182
|
+
}
|
|
3183
|
+
const remaining = length - fullBlocks * 64;
|
|
3184
|
+
const tail = new Uint8Array(remaining + 1 + 8 > 64 ? 128 : 64);
|
|
3185
|
+
tail.set(bytes.subarray(fullBlocks * 64));
|
|
3186
|
+
tail[remaining] = 128;
|
|
3187
|
+
const tailView = new DataView(tail.buffer);
|
|
3188
|
+
const bitLengthHigh = Math.floor(length / 536870912);
|
|
3189
|
+
const bitLengthLow = length << 3 >>> 0;
|
|
3190
|
+
tailView.setUint32(tail.length - 8, bitLengthHigh);
|
|
3191
|
+
tailView.setUint32(tail.length - 4, bitLengthLow);
|
|
3192
|
+
for (let offset = 0; offset < tail.length; offset += 64) {
|
|
3193
|
+
compress(h, w, tailView, offset);
|
|
3194
|
+
}
|
|
3195
|
+
let hex = "";
|
|
3196
|
+
for (let i = 0; i < 8; i++) {
|
|
3197
|
+
hex += h[i].toString(16).padStart(8, "0");
|
|
3198
|
+
}
|
|
3199
|
+
return hex;
|
|
3200
|
+
}
|
|
3201
|
+
function sha256HexOfUtf8(input) {
|
|
3202
|
+
return sha256HexOfBytes(encoder.encode(input));
|
|
3203
|
+
}
|
|
3204
|
+
|
|
3205
|
+
// ../core/src/inventory-guard.ts
|
|
3206
|
+
var INVENTORY_GUARD_DOMAIN = "cooperating-local-writers-v1";
|
|
3207
|
+
var InventoryGuardUnsupported = class extends Error {
|
|
3208
|
+
written = false;
|
|
3209
|
+
reason;
|
|
3210
|
+
constructor(reason) {
|
|
3211
|
+
super(`Inventory guard unsupported: ${reason}`);
|
|
3212
|
+
this.name = "InventoryGuardUnsupported";
|
|
3213
|
+
this.reason = reason;
|
|
3214
|
+
}
|
|
3215
|
+
};
|
|
3216
|
+
var InventoryGuardConflict = class extends Error {
|
|
3217
|
+
written = false;
|
|
3218
|
+
reason;
|
|
3219
|
+
constructor(reason) {
|
|
3220
|
+
super(`Inventory guard premise changed: ${reason}`);
|
|
3221
|
+
this.name = "InventoryGuardConflict";
|
|
3222
|
+
this.reason = reason;
|
|
3223
|
+
}
|
|
3224
|
+
};
|
|
3225
|
+
var capabilityOwners = /* @__PURE__ */ new WeakMap();
|
|
3226
|
+
function bindInventoryGuard(owner, guard) {
|
|
3227
|
+
capabilityOwners.set(guard, owner);
|
|
3228
|
+
return guard;
|
|
3229
|
+
}
|
|
3230
|
+
function assertInventoryGuardBound(count) {
|
|
3231
|
+
if (count > 1e4) throw new InventoryGuardUnsupported("inventory_document_bound");
|
|
3232
|
+
}
|
|
3233
|
+
function copyData(value, active = /* @__PURE__ */ new Set(), budget = { nodes: 1e5 }) {
|
|
3234
|
+
if (--budget.nodes < 0) throw new InvalidInputError("Inventory guard input exceeds its data bound.");
|
|
3235
|
+
if (value === null || typeof value === "string" || typeof value === "boolean") return value;
|
|
3236
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
3237
|
+
if (typeof value !== "object") throw new InvalidInputError("Inventory guard accepts finite plain data only.");
|
|
3238
|
+
if (active.has(value)) throw new InvalidInputError("Inventory guard input is cyclic.");
|
|
3239
|
+
const array = Array.isArray(value);
|
|
3240
|
+
if (Object.getPrototypeOf(value) !== (array ? Array.prototype : Object.prototype) && Object.getPrototypeOf(value) !== null) {
|
|
3241
|
+
throw new InvalidInputError("Inventory guard accepts plain objects and arrays only.");
|
|
3242
|
+
}
|
|
3243
|
+
active.add(value);
|
|
3244
|
+
const result = array ? [] : /* @__PURE__ */ Object.create(null);
|
|
3245
|
+
if (array && Object.keys(value).length !== value.length) throw new InvalidInputError("Inventory guard input cannot carry sparse arrays or extra keys.");
|
|
3246
|
+
for (const key of Reflect.ownKeys(value)) {
|
|
3247
|
+
if (array && key === "length") continue;
|
|
3248
|
+
if (array && (typeof key !== "string" || !/^(0|[1-9][0-9]*)$/.test(key))) throw new InvalidInputError("Inventory guard arrays require indexed data only.");
|
|
3249
|
+
if (typeof key !== "string") throw new InvalidInputError("Inventory guard input cannot carry symbol keys.");
|
|
3250
|
+
const property = Object.getOwnPropertyDescriptor(value, key);
|
|
3251
|
+
if (!property.enumerable || !("value" in property)) throw new InvalidInputError("Inventory guard input cannot carry accessors or hidden data.");
|
|
3252
|
+
Object.defineProperty(result, key, { value: copyData(property.value, active, budget), enumerable: true, configurable: true, writable: true });
|
|
3253
|
+
}
|
|
3254
|
+
if (array && result.length !== value.length) throw new InvalidInputError("Inventory guard input cannot carry sparse arrays.");
|
|
3255
|
+
active.delete(value);
|
|
3256
|
+
return result;
|
|
3257
|
+
}
|
|
3258
|
+
function record(value) {
|
|
3259
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) throw new InvalidInputError("Inventory guard expected an object.");
|
|
3260
|
+
return value;
|
|
3261
|
+
}
|
|
3262
|
+
function keys(value, allowed) {
|
|
3263
|
+
if (Object.keys(value).some((key) => !allowed.includes(key))) throw new InvalidInputError("Inventory guard input has unsupported fields.");
|
|
3264
|
+
}
|
|
3265
|
+
function version(value) {
|
|
3266
|
+
if (typeof value !== "string" || !/^sha256:[0-9a-f]{64}$/.test(value)) throw new InvalidInputError("Inventory guard requires exact content versions.");
|
|
3267
|
+
}
|
|
3268
|
+
function captureInventoryGuardRequest(input) {
|
|
3269
|
+
const data = record(copyData(input));
|
|
3270
|
+
keys(data, ["target", "domain", "inventory", "id", "expectedVersion", "doc", "options"]);
|
|
3271
|
+
const target = record(data.target);
|
|
3272
|
+
keys(target, ["contract", "domain", "adapter", "store", "root_version", "edition"]);
|
|
3273
|
+
if (target.contract !== "inventory-guard/v1" || target.domain !== INVENTORY_GUARD_DOMAIN || data.domain !== INVENTORY_GUARD_DOMAIN) {
|
|
3274
|
+
throw new InventoryGuardUnsupported("domain_or_contract");
|
|
3275
|
+
}
|
|
3276
|
+
if (!["memory", "filesystem"].includes(String(target.adapter)) || typeof target.store !== "string" || target.store.length === 0 || !["0.1", "0.2"].includes(String(target.edition))) throw new InvalidInputError("Invalid inventory guard target.");
|
|
3277
|
+
version(target.root_version);
|
|
3278
|
+
if (typeof data.id !== "string") throw new InvalidInputError("Inventory guard requires a target id.");
|
|
3279
|
+
assertSafeConceptId(data.id);
|
|
3280
|
+
if (isReservedFile(pathFromConceptId(data.id))) throw new InvalidInputError("Inventory guard target must be a concept.");
|
|
3281
|
+
version(data.expectedVersion);
|
|
3282
|
+
if (!Array.isArray(data.inventory)) throw new InvalidInputError("Inventory guard requires a complete inventory.");
|
|
3283
|
+
assertInventoryGuardBound(data.inventory.length);
|
|
3284
|
+
let previous;
|
|
3285
|
+
for (const raw of data.inventory) {
|
|
3286
|
+
const row = record(raw);
|
|
3287
|
+
keys(row, ["id", "version"]);
|
|
3288
|
+
if (typeof row.id !== "string") throw new InvalidInputError("Inventory guard inventory id is invalid.");
|
|
3289
|
+
assertSafeConceptId(row.id);
|
|
3290
|
+
if (isReservedFile(pathFromConceptId(row.id)) || previous !== void 0 && compareStorageKeys(previous, row.id) >= 0) throw new InvalidInputError("Inventory guard inventory must be sorted, unique concepts.");
|
|
3291
|
+
version(row.version);
|
|
3292
|
+
previous = row.id;
|
|
3293
|
+
}
|
|
3294
|
+
if (!data.inventory.some((row) => row.id === data.id && row.version === data.expectedVersion)) throw new InvalidInputError("Inventory guard target/version is missing from inventory.");
|
|
3295
|
+
const doc = record(data.doc);
|
|
3296
|
+
keys(doc, ["id", "frontmatter", "body"]);
|
|
3297
|
+
if (doc.id !== data.id || typeof doc.body !== "string") throw new InvalidInputError("Inventory guard candidate identity/body is invalid.");
|
|
3298
|
+
record(doc.frontmatter);
|
|
3299
|
+
if (data.options !== void 0) {
|
|
3300
|
+
const options = record(data.options);
|
|
3301
|
+
keys(options, ["actor", "agent"]);
|
|
3302
|
+
if (Object.values(options).some((value) => typeof value !== "string")) throw new InvalidInputError("Inventory guard attribution must be strings.");
|
|
3303
|
+
}
|
|
3304
|
+
return data;
|
|
3305
|
+
}
|
|
3306
|
+
function guardEdition(content) {
|
|
3307
|
+
if (content === null) throw new InventoryGuardUnsupported("root_metadata_absent");
|
|
3308
|
+
const edition = parseLeadingFrontmatter(content, "index.md").okf_version;
|
|
3309
|
+
if (edition !== "0.1" && edition !== "0.2") throw new InventoryGuardUnsupported("root_edition_unestablished");
|
|
3310
|
+
return edition;
|
|
3311
|
+
}
|
|
3312
|
+
function compareInventoryPremises(expected, current, inventory) {
|
|
3313
|
+
if (expected.target.adapter !== current.adapter || expected.target.store !== current.store) throw new InventoryGuardConflict("identity");
|
|
3314
|
+
if (expected.target.edition !== current.edition) throw new InventoryGuardConflict("edition");
|
|
3315
|
+
if (expected.target.root_version !== current.root_version) throw new InventoryGuardConflict("root_metadata");
|
|
3316
|
+
if (expected.inventory.length !== inventory.length || expected.inventory.some((row, index) => row.id !== inventory[index]?.id)) throw new InventoryGuardConflict("membership");
|
|
3317
|
+
if (expected.inventory.some((row, index) => row.version !== inventory[index].version)) throw new InventoryGuardConflict("version");
|
|
3318
|
+
if (!inventory.some((row) => row.id === expected.id && row.version === expected.expectedVersion)) throw new InventoryGuardConflict("target_version");
|
|
3319
|
+
}
|
|
3320
|
+
function inventoryDigest(inventory) {
|
|
3321
|
+
return `sha256:${sha256HexOfUtf8(JSON.stringify(inventory.map((row) => [row.id, row.version])))}`;
|
|
3322
|
+
}
|
|
3323
|
+
|
|
3324
|
+
// ../core/src/frontmatter.ts
|
|
3325
|
+
var import_js_yaml2 = __toESM(require_js_yaml2(), 1);
|
|
3326
|
+
var YAML_TIMESTAMP_TAG = "tag:yaml.org,2002:timestamp";
|
|
3327
|
+
function requireYamlTimestampType() {
|
|
3328
|
+
const type = import_js_yaml2.default.DEFAULT_SAFE_SCHEMA.implicit.find(
|
|
3329
|
+
(candidate) => candidate.tag === YAML_TIMESTAMP_TAG
|
|
3330
|
+
);
|
|
3331
|
+
if (!type) throw new Error("js-yaml safe schema is missing its timestamp type");
|
|
3332
|
+
return type;
|
|
3333
|
+
}
|
|
3334
|
+
var yamlTimestampType = requireYamlTimestampType();
|
|
3335
|
+
var stringTimestampType = new import_js_yaml2.default.Type(YAML_TIMESTAMP_TAG, {
|
|
3336
|
+
kind: "scalar",
|
|
3337
|
+
resolve: (value) => yamlTimestampType.resolve(value),
|
|
3338
|
+
construct: (value) => value
|
|
3339
|
+
});
|
|
3340
|
+
var losslessDateSchema = new import_js_yaml2.default.Schema({
|
|
3341
|
+
include: [import_js_yaml2.default.DEFAULT_SAFE_SCHEMA],
|
|
3342
|
+
implicit: [stringTimestampType]
|
|
3343
|
+
});
|
|
3344
|
+
var yamlEngine = {
|
|
3345
|
+
parse(input) {
|
|
3346
|
+
return import_js_yaml2.default.safeLoad(input, { schema: losslessDateSchema }) ?? {};
|
|
3347
|
+
}
|
|
3348
|
+
};
|
|
3349
|
+
function normalizeFrontmatter(data, okfVersion) {
|
|
3350
|
+
const out = { ...data };
|
|
3351
|
+
if (okfVersion === "0.2") return out;
|
|
3352
|
+
const value = out.timestamp;
|
|
3353
|
+
if (value instanceof Date) {
|
|
3354
|
+
out.timestamp = value.toISOString();
|
|
3355
|
+
} else if (typeof value === "number" && Number.isFinite(value)) {
|
|
3356
|
+
out.timestamp = new Date(value).toISOString();
|
|
3357
|
+
} else if (typeof value === "string" && yamlTimestampType.resolve(value)) {
|
|
3358
|
+
const parsed = yamlTimestampType.construct(value);
|
|
3359
|
+
if (parsed instanceof Date) out.timestamp = parsed.toISOString();
|
|
3360
|
+
}
|
|
3361
|
+
return out;
|
|
3362
|
+
}
|
|
3363
|
+
function parseMarkdown(raw, context, options = {}) {
|
|
3364
|
+
const split = splitLeadingFrontmatter(raw, context);
|
|
3365
|
+
if (!("yamlSource" in split)) return { frontmatter: {}, body: split.body };
|
|
3366
|
+
return { frontmatter: parseFrontmatter(split.yamlSource, context, options), body: split.body };
|
|
3367
|
+
}
|
|
3368
|
+
function parseFrontmatter(source, context, options = {}) {
|
|
3369
|
+
let parsed;
|
|
3370
|
+
try {
|
|
3371
|
+
parsed = yamlEngine.parse(source);
|
|
3372
|
+
} catch (err) {
|
|
3373
|
+
throw new MalformedDocumentError(context, err);
|
|
3374
|
+
}
|
|
3375
|
+
return normalizeFrontmatter(parsed, options.okfVersion);
|
|
3376
|
+
}
|
|
3377
|
+
function stringifyFrontmatter(data) {
|
|
3378
|
+
return import_js_yaml2.default.safeDump(data).trim();
|
|
3379
|
+
}
|
|
3380
|
+
function normalizeDocumentBodyForStorage(body) {
|
|
3381
|
+
return body.endsWith("\n") ? body : `${body}
|
|
3382
|
+
`;
|
|
3383
|
+
}
|
|
3384
|
+
function stringifyWithData(data, body) {
|
|
3385
|
+
return stringifyWithSerializedFrontmatter(stringifyFrontmatter(data), body);
|
|
3386
|
+
}
|
|
3387
|
+
function stringifyWithSerializedFrontmatter(dumped, body) {
|
|
3388
|
+
const content = body ?? "";
|
|
3389
|
+
const newline = (value) => value.endsWith("\n") ? value : `${value}
|
|
3390
|
+
`;
|
|
3391
|
+
if (dumped === "{}") return normalizeDocumentBodyForStorage(content);
|
|
3392
|
+
return `---
|
|
3393
|
+
${newline(dumped)}---
|
|
3394
|
+
${normalizeDocumentBodyForStorage(content)}`;
|
|
3395
|
+
}
|
|
3396
|
+
function stringifyDoc(frontmatter2, body) {
|
|
3397
|
+
return stringifyWithData(frontmatter2, body);
|
|
3105
3398
|
}
|
|
3106
3399
|
|
|
3107
3400
|
// ../core/src/links.ts
|
|
@@ -3427,12 +3720,25 @@ function parseTimestamp(ts, okfVersion) {
|
|
|
3427
3720
|
return Number.isNaN(ms) ? null : ms;
|
|
3428
3721
|
}
|
|
3429
3722
|
|
|
3723
|
+
// ../core/src/okf-authored-values.ts
|
|
3724
|
+
function isOkfRecord(value) {
|
|
3725
|
+
if (value === null || typeof value !== "object") return false;
|
|
3726
|
+
const prototype = Object.getPrototypeOf(value);
|
|
3727
|
+
return prototype === Object.prototype || prototype === null;
|
|
3728
|
+
}
|
|
3729
|
+
|
|
3430
3730
|
// ../core/src/okf-lifecycle.ts
|
|
3431
3731
|
var OKF_LIFECYCLE_STATUSES = Object.freeze(["draft", "stable", "deprecated"]);
|
|
3432
3732
|
function isOkfLifecycleStatus(value) {
|
|
3433
3733
|
return typeof value === "string" && OKF_LIFECYCLE_STATUSES.includes(value);
|
|
3434
3734
|
}
|
|
3435
3735
|
|
|
3736
|
+
// ../core/src/okf-standard-fields.ts
|
|
3737
|
+
var OKF_STANDARD_FIELD_NAMES = ["type", "title", "description", "resource", "tags", "status", "sources", "generated", "verified", "stale_after", "usage_window", "runtime", "computation", "parameters", "executor", "attester", "okf_version"];
|
|
3738
|
+
function isOkfStandardField(field) {
|
|
3739
|
+
return OKF_STANDARD_FIELD_NAMES.includes(field);
|
|
3740
|
+
}
|
|
3741
|
+
|
|
3436
3742
|
// ../core/src/mutation-attribution.ts
|
|
3437
3743
|
var SUPERBEE_UPDATED_BY_FIELD = "superbee_updated_by";
|
|
3438
3744
|
function nonEmptyString(value) {
|
|
@@ -3442,24 +3748,6 @@ function mutationActorFromFrontmatter(frontmatter2) {
|
|
|
3442
3748
|
return nonEmptyString(frontmatter2[SUPERBEE_UPDATED_BY_FIELD]) ?? nonEmptyString(frontmatter2.updated_by) ?? nonEmptyString(frontmatter2.actor);
|
|
3443
3749
|
}
|
|
3444
3750
|
|
|
3445
|
-
// ../core/src/portable-frontmatter.ts
|
|
3446
|
-
var import_js_yaml2 = __toESM(require_js_yaml2(), 1);
|
|
3447
|
-
function parseLeadingFrontmatter(raw, context) {
|
|
3448
|
-
const split = splitLeadingFrontmatter(raw, context);
|
|
3449
|
-
if (!("yamlSource" in split)) return {};
|
|
3450
|
-
try {
|
|
3451
|
-
const parsed = import_js_yaml2.default.safeLoad(split.yamlSource);
|
|
3452
|
-
if (parsed === void 0 || parsed === null) return {};
|
|
3453
|
-
if (typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
3454
|
-
throw new TypeError("YAML frontmatter must be a mapping");
|
|
3455
|
-
}
|
|
3456
|
-
return parsed;
|
|
3457
|
-
} catch (error) {
|
|
3458
|
-
if (error instanceof MalformedDocumentError) throw error;
|
|
3459
|
-
throw new MalformedDocumentError(context, error);
|
|
3460
|
-
}
|
|
3461
|
-
}
|
|
3462
|
-
|
|
3463
3751
|
// ../core/src/query-filter.ts
|
|
3464
3752
|
function matchesFilter(doc, filter) {
|
|
3465
3753
|
if (filter.prefix && !doc.id.startsWith(filter.prefix)) return false;
|
|
@@ -3565,10 +3853,10 @@ async function queryHeads(backend, filter = {}, options = {}) {
|
|
|
3565
3853
|
rows.sort((a, b) => a.id.localeCompare(b.id));
|
|
3566
3854
|
return rows;
|
|
3567
3855
|
}
|
|
3568
|
-
return (await scanMatching(backend, filter, options.onSkip)).map(({ doc, version }) => ({
|
|
3856
|
+
return (await scanMatching(backend, filter, options.onSkip)).map(({ doc, version: version2 }) => ({
|
|
3569
3857
|
id: doc.id,
|
|
3570
3858
|
frontmatter: doc.frontmatter,
|
|
3571
|
-
version
|
|
3859
|
+
version: version2
|
|
3572
3860
|
}));
|
|
3573
3861
|
}
|
|
3574
3862
|
function normalizeEdgeSelector(raw) {
|
|
@@ -3680,13 +3968,13 @@ function snapshotHostPolicy(input, seen = /* @__PURE__ */ new WeakMap()) {
|
|
|
3680
3968
|
if (existing) return existing;
|
|
3681
3969
|
const result = Array.isArray(input) ? [] : {};
|
|
3682
3970
|
seen.set(input, result);
|
|
3683
|
-
const
|
|
3971
|
+
const keys2 = /* @__PURE__ */ new Set();
|
|
3684
3972
|
for (let owner = input; owner && owner !== Object.prototype && owner !== Array.prototype; owner = Object.getPrototypeOf(owner)) {
|
|
3685
3973
|
for (const key of Reflect.ownKeys(owner)) {
|
|
3686
|
-
if (key !== "constructor" && !(Array.isArray(input) && key === "length"))
|
|
3974
|
+
if (key !== "constructor" && !(Array.isArray(input) && key === "length")) keys2.add(key);
|
|
3687
3975
|
}
|
|
3688
3976
|
}
|
|
3689
|
-
for (const key of
|
|
3977
|
+
for (const key of keys2) {
|
|
3690
3978
|
const value = input[key];
|
|
3691
3979
|
Object.defineProperty(result, key, {
|
|
3692
3980
|
value: typeof value === "function" ? value.bind(result) : value && typeof value === "object" ? snapshotHostPolicy(value, seen) : value,
|
|
@@ -3811,14 +4099,14 @@ async function readOwnerRecord(lockPath) {
|
|
|
3811
4099
|
}
|
|
3812
4100
|
async function resolveOwnerRecord(lockPath, started, waitMs, pollMs) {
|
|
3813
4101
|
while (true) {
|
|
3814
|
-
const
|
|
3815
|
-
if (
|
|
4102
|
+
const record2 = await readOwnerRecord(lockPath);
|
|
4103
|
+
if (record2.state !== "unreadable" || Date.now() - started >= waitMs) return record2;
|
|
3816
4104
|
await delay(pollMs);
|
|
3817
4105
|
}
|
|
3818
4106
|
}
|
|
3819
4107
|
async function readOwner(lockPath) {
|
|
3820
|
-
const
|
|
3821
|
-
return
|
|
4108
|
+
const record2 = await readOwnerRecord(lockPath);
|
|
4109
|
+
return record2.state === "record" ? record2.owner : null;
|
|
3822
4110
|
}
|
|
3823
4111
|
function processExists(pid) {
|
|
3824
4112
|
try {
|
|
@@ -4013,12 +4301,12 @@ async function claimLockPath(lockPath, owner, waitMs, pollMs, policy) {
|
|
|
4013
4301
|
}
|
|
4014
4302
|
async function rollBackOwnClaim(lockPath, owner, claimed, waitMs, pollMs, policy) {
|
|
4015
4303
|
const started = Date.now();
|
|
4016
|
-
const
|
|
4017
|
-
if (
|
|
4018
|
-
if (
|
|
4304
|
+
const record2 = await resolveOwnerRecord(lockPath, started, waitMs, pollMs);
|
|
4305
|
+
if (record2.state === "record") {
|
|
4306
|
+
if (record2.owner.token === owner.token) await removeReleasedLock(lockPath, owner, started, waitMs, pollMs, policy);
|
|
4019
4307
|
return;
|
|
4020
4308
|
}
|
|
4021
|
-
if (
|
|
4309
|
+
if (record2.state === "unreadable" || !await isClaimedDirectory(lockPath, claimed)) return;
|
|
4022
4310
|
const remnant = releasedLockRemnantPath(lockPath, owner);
|
|
4023
4311
|
await fs.rename(lockPath, remnant);
|
|
4024
4312
|
await fs.rm(remnant, { recursive: true, force: true });
|
|
@@ -4181,12 +4469,62 @@ async function existingAnchor(resolved) {
|
|
|
4181
4469
|
candidate = parent;
|
|
4182
4470
|
}
|
|
4183
4471
|
}
|
|
4184
|
-
async function
|
|
4185
|
-
const foldedRel = relSegments(rel).map(foldSegment).join("/");
|
|
4472
|
+
async function foldedPhysicalRoot(root) {
|
|
4186
4473
|
const { anchor, tail } = await existingAnchor(path2.resolve(root));
|
|
4187
4474
|
const anchorSegments = anchor.split(path2.sep).filter((segment, index) => index === 0 || segment !== "");
|
|
4188
|
-
|
|
4189
|
-
|
|
4475
|
+
return [...anchorSegments, ...tail].map(foldSegment).join("/");
|
|
4476
|
+
}
|
|
4477
|
+
async function identityKey(root, rel) {
|
|
4478
|
+
const foldedRel = relSegments(rel).map(foldSegment).join("/");
|
|
4479
|
+
return createHash2("sha256").update(`superbee-identity/v1\0${await foldedPhysicalRoot(root)}\0${foldedRel}`).digest("hex");
|
|
4480
|
+
}
|
|
4481
|
+
async function filesystemRootMutationKey(root) {
|
|
4482
|
+
return createHash2("sha256").update(`superbee-root-mutation/v1\0${await foldedPhysicalRoot(root)}`).digest("hex");
|
|
4483
|
+
}
|
|
4484
|
+
async function filesystemRootWitness(port, root) {
|
|
4485
|
+
const physical = await fs2.realpath(root);
|
|
4486
|
+
const witnesses = [];
|
|
4487
|
+
let current = physical;
|
|
4488
|
+
for (; ; ) {
|
|
4489
|
+
const witness = await port.probe(current);
|
|
4490
|
+
if (!witness || witness.kind !== "directory") throw new InvalidInputError("Inventory guard root identity is unavailable.");
|
|
4491
|
+
witnesses.push([current, witness.dev, witness.ino]);
|
|
4492
|
+
const parent = path2.dirname(current);
|
|
4493
|
+
if (parent === current) break;
|
|
4494
|
+
current = parent;
|
|
4495
|
+
}
|
|
4496
|
+
return createHash2("sha256").update(JSON.stringify(witnesses)).digest("hex");
|
|
4497
|
+
}
|
|
4498
|
+
var rootMutationQueues = /* @__PURE__ */ new Map();
|
|
4499
|
+
function createFilesystemMutationCoordinator(_port, root, hostPolicy) {
|
|
4500
|
+
const policy = captureFilesystemHostPolicy(hostPolicy);
|
|
4501
|
+
let lockRoot;
|
|
4502
|
+
const namespace = () => lockRoot ??= filesystemMutationLockRoot(root, policy);
|
|
4503
|
+
return Object.freeze({
|
|
4504
|
+
namespace,
|
|
4505
|
+
async run(body) {
|
|
4506
|
+
const key = await filesystemRootMutationKey(root);
|
|
4507
|
+
const lockRoot2 = namespace();
|
|
4508
|
+
const queueKey = `${lockRoot2}:${key}`;
|
|
4509
|
+
const previous = rootMutationQueues.get(queueKey) ?? Promise.resolve();
|
|
4510
|
+
const run = previous.then(async () => {
|
|
4511
|
+
const release = await acquireFilesystemIdentityLock(key, root, { portableRoot: root, lockRoot: lockRoot2, hostPolicy: policy });
|
|
4512
|
+
try {
|
|
4513
|
+
return await body();
|
|
4514
|
+
} finally {
|
|
4515
|
+
await release();
|
|
4516
|
+
}
|
|
4517
|
+
});
|
|
4518
|
+
const settled = run.then(() => {
|
|
4519
|
+
}, () => {
|
|
4520
|
+
});
|
|
4521
|
+
rootMutationQueues.set(queueKey, settled);
|
|
4522
|
+
void settled.then(() => {
|
|
4523
|
+
if (rootMutationQueues.get(queueKey) === settled) rootMutationQueues.delete(queueKey);
|
|
4524
|
+
});
|
|
4525
|
+
return run;
|
|
4526
|
+
}
|
|
4527
|
+
});
|
|
4190
4528
|
}
|
|
4191
4529
|
function sameWitness(a, b) {
|
|
4192
4530
|
return a.dev === b.dev && a.ino === b.ino;
|
|
@@ -4720,162 +5058,6 @@ function createNodeFilesystemIdentityPort(hostPolicy) {
|
|
|
4720
5058
|
});
|
|
4721
5059
|
}
|
|
4722
5060
|
|
|
4723
|
-
// ../core/src/sha256.ts
|
|
4724
|
-
var K = new Uint32Array([
|
|
4725
|
-
1116352408,
|
|
4726
|
-
1899447441,
|
|
4727
|
-
3049323471,
|
|
4728
|
-
3921009573,
|
|
4729
|
-
961987163,
|
|
4730
|
-
1508970993,
|
|
4731
|
-
2453635748,
|
|
4732
|
-
2870763221,
|
|
4733
|
-
3624381080,
|
|
4734
|
-
310598401,
|
|
4735
|
-
607225278,
|
|
4736
|
-
1426881987,
|
|
4737
|
-
1925078388,
|
|
4738
|
-
2162078206,
|
|
4739
|
-
2614888103,
|
|
4740
|
-
3248222580,
|
|
4741
|
-
3835390401,
|
|
4742
|
-
4022224774,
|
|
4743
|
-
264347078,
|
|
4744
|
-
604807628,
|
|
4745
|
-
770255983,
|
|
4746
|
-
1249150122,
|
|
4747
|
-
1555081692,
|
|
4748
|
-
1996064986,
|
|
4749
|
-
2554220882,
|
|
4750
|
-
2821834349,
|
|
4751
|
-
2952996808,
|
|
4752
|
-
3210313671,
|
|
4753
|
-
3336571891,
|
|
4754
|
-
3584528711,
|
|
4755
|
-
113926993,
|
|
4756
|
-
338241895,
|
|
4757
|
-
666307205,
|
|
4758
|
-
773529912,
|
|
4759
|
-
1294757372,
|
|
4760
|
-
1396182291,
|
|
4761
|
-
1695183700,
|
|
4762
|
-
1986661051,
|
|
4763
|
-
2177026350,
|
|
4764
|
-
2456956037,
|
|
4765
|
-
2730485921,
|
|
4766
|
-
2820302411,
|
|
4767
|
-
3259730800,
|
|
4768
|
-
3345764771,
|
|
4769
|
-
3516065817,
|
|
4770
|
-
3600352804,
|
|
4771
|
-
4094571909,
|
|
4772
|
-
275423344,
|
|
4773
|
-
430227734,
|
|
4774
|
-
506948616,
|
|
4775
|
-
659060556,
|
|
4776
|
-
883997877,
|
|
4777
|
-
958139571,
|
|
4778
|
-
1322822218,
|
|
4779
|
-
1537002063,
|
|
4780
|
-
1747873779,
|
|
4781
|
-
1955562222,
|
|
4782
|
-
2024104815,
|
|
4783
|
-
2227730452,
|
|
4784
|
-
2361852424,
|
|
4785
|
-
2428436474,
|
|
4786
|
-
2756734187,
|
|
4787
|
-
3204031479,
|
|
4788
|
-
3329325298
|
|
4789
|
-
]);
|
|
4790
|
-
var INITIAL_STATE = new Uint32Array([
|
|
4791
|
-
1779033703,
|
|
4792
|
-
3144134277,
|
|
4793
|
-
1013904242,
|
|
4794
|
-
2773480762,
|
|
4795
|
-
1359893119,
|
|
4796
|
-
2600822924,
|
|
4797
|
-
528734635,
|
|
4798
|
-
1541459225
|
|
4799
|
-
]);
|
|
4800
|
-
var encoder = new TextEncoder();
|
|
4801
|
-
function rotr(value, bits) {
|
|
4802
|
-
return value >>> bits | value << 32 - bits;
|
|
4803
|
-
}
|
|
4804
|
-
function compress(h, w, view, offset) {
|
|
4805
|
-
for (let i = 0; i < 16; i++) {
|
|
4806
|
-
w[i] = view.getUint32(offset + i * 4);
|
|
4807
|
-
}
|
|
4808
|
-
for (let i = 16; i < 64; i++) {
|
|
4809
|
-
const w15 = w[i - 15];
|
|
4810
|
-
const w2 = w[i - 2];
|
|
4811
|
-
const s0 = rotr(w15, 7) ^ rotr(w15, 18) ^ w15 >>> 3;
|
|
4812
|
-
const s1 = rotr(w2, 17) ^ rotr(w2, 19) ^ w2 >>> 10;
|
|
4813
|
-
w[i] = w[i - 16] + s0 + w[i - 7] + s1 >>> 0;
|
|
4814
|
-
}
|
|
4815
|
-
let a = h[0];
|
|
4816
|
-
let b = h[1];
|
|
4817
|
-
let c = h[2];
|
|
4818
|
-
let d = h[3];
|
|
4819
|
-
let e = h[4];
|
|
4820
|
-
let f = h[5];
|
|
4821
|
-
let g = h[6];
|
|
4822
|
-
let hh = h[7];
|
|
4823
|
-
for (let i = 0; i < 64; i++) {
|
|
4824
|
-
const S1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25);
|
|
4825
|
-
const ch = e & f ^ ~e & g;
|
|
4826
|
-
const t1 = hh + S1 + ch + K[i] + w[i] >>> 0;
|
|
4827
|
-
const S0 = rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22);
|
|
4828
|
-
const maj = a & b ^ a & c ^ b & c;
|
|
4829
|
-
const t2 = S0 + maj >>> 0;
|
|
4830
|
-
hh = g;
|
|
4831
|
-
g = f;
|
|
4832
|
-
f = e;
|
|
4833
|
-
e = d + t1 >>> 0;
|
|
4834
|
-
d = c;
|
|
4835
|
-
c = b;
|
|
4836
|
-
b = a;
|
|
4837
|
-
a = t1 + t2 >>> 0;
|
|
4838
|
-
}
|
|
4839
|
-
h[0] = h[0] + a >>> 0;
|
|
4840
|
-
h[1] = h[1] + b >>> 0;
|
|
4841
|
-
h[2] = h[2] + c >>> 0;
|
|
4842
|
-
h[3] = h[3] + d >>> 0;
|
|
4843
|
-
h[4] = h[4] + e >>> 0;
|
|
4844
|
-
h[5] = h[5] + f >>> 0;
|
|
4845
|
-
h[6] = h[6] + g >>> 0;
|
|
4846
|
-
h[7] = h[7] + hh >>> 0;
|
|
4847
|
-
}
|
|
4848
|
-
function sha256HexOfBytes(bytes) {
|
|
4849
|
-
const h = new Uint32Array(INITIAL_STATE);
|
|
4850
|
-
const w = new Uint32Array(64);
|
|
4851
|
-
const length = bytes.byteLength;
|
|
4852
|
-
const view = new DataView(bytes.buffer, bytes.byteOffset, length);
|
|
4853
|
-
const fullBlocks = length >>> 6;
|
|
4854
|
-
for (let block = 0; block < fullBlocks; block++) {
|
|
4855
|
-
compress(h, w, view, block * 64);
|
|
4856
|
-
}
|
|
4857
|
-
const remaining = length - fullBlocks * 64;
|
|
4858
|
-
const tail = new Uint8Array(remaining + 1 + 8 > 64 ? 128 : 64);
|
|
4859
|
-
tail.set(bytes.subarray(fullBlocks * 64));
|
|
4860
|
-
tail[remaining] = 128;
|
|
4861
|
-
const tailView = new DataView(tail.buffer);
|
|
4862
|
-
const bitLengthHigh = Math.floor(length / 536870912);
|
|
4863
|
-
const bitLengthLow = length << 3 >>> 0;
|
|
4864
|
-
tailView.setUint32(tail.length - 8, bitLengthHigh);
|
|
4865
|
-
tailView.setUint32(tail.length - 4, bitLengthLow);
|
|
4866
|
-
for (let offset = 0; offset < tail.length; offset += 64) {
|
|
4867
|
-
compress(h, w, tailView, offset);
|
|
4868
|
-
}
|
|
4869
|
-
let hex = "";
|
|
4870
|
-
for (let i = 0; i < 8; i++) {
|
|
4871
|
-
hex += h[i].toString(16).padStart(8, "0");
|
|
4872
|
-
}
|
|
4873
|
-
return hex;
|
|
4874
|
-
}
|
|
4875
|
-
function sha256HexOfUtf8(input) {
|
|
4876
|
-
return sha256HexOfBytes(encoder.encode(input));
|
|
4877
|
-
}
|
|
4878
|
-
|
|
4879
5061
|
// ../core/src/versioning.ts
|
|
4880
5062
|
function sha256Hex(input) {
|
|
4881
5063
|
return sha256HexOfUtf8(input);
|
|
@@ -4935,6 +5117,66 @@ function reservedPath(dir, name) {
|
|
|
4935
5117
|
var FilesystemBackend = class _FilesystemBackend {
|
|
4936
5118
|
#root;
|
|
4937
5119
|
#port;
|
|
5120
|
+
#coordinator;
|
|
5121
|
+
/** The coordinator is private: no transaction callback or held-root capability escapes. */
|
|
5122
|
+
#withRootMutation(body) {
|
|
5123
|
+
return this.#coordinator.run(body);
|
|
5124
|
+
}
|
|
5125
|
+
#mutateExact(rel, body) {
|
|
5126
|
+
return this.#withRootMutation(() => mutateExact(this.#port, this.#root, rel, body));
|
|
5127
|
+
}
|
|
5128
|
+
#assertInventoryGuard() {
|
|
5129
|
+
if (Object.getPrototypeOf(this) !== _FilesystemBackend.prototype || ["read", "readMany", "list", "write", "delete", "writeReserved", "writeBlob", "deleteBlob", "readReserved"].some((name) => this[name] !== _FilesystemBackend.prototype[name])) {
|
|
5130
|
+
throw new InventoryGuardUnsupported("unqualified_filesystem_override");
|
|
5131
|
+
}
|
|
5132
|
+
}
|
|
5133
|
+
get inventoryGuard() {
|
|
5134
|
+
this.#assertInventoryGuard();
|
|
5135
|
+
return bindInventoryGuard(this, {
|
|
5136
|
+
observeTarget: () => this.#withRootMutation(() => {
|
|
5137
|
+
this.#assertInventoryGuard();
|
|
5138
|
+
return this.#guardTarget();
|
|
5139
|
+
}),
|
|
5140
|
+
compareInventoryAndWrite: async (input) => {
|
|
5141
|
+
const request = captureInventoryGuardRequest(input);
|
|
5142
|
+
const raw = stringifyDoc(request.doc.frontmatter, request.doc.body);
|
|
5143
|
+
return this.#withRootMutation(async () => {
|
|
5144
|
+
this.#assertInventoryGuard();
|
|
5145
|
+
const target = await this.#guardTarget();
|
|
5146
|
+
const inventory = [];
|
|
5147
|
+
const ids = await this.list();
|
|
5148
|
+
assertInventoryGuardBound(ids.length);
|
|
5149
|
+
const deadline = performance.now() + 5e3;
|
|
5150
|
+
for (const id of ids) {
|
|
5151
|
+
if (performance.now() > deadline) throw new InventoryGuardUnsupported("inventory_scan_time_bound");
|
|
5152
|
+
const raw2 = await readRawFilesystemDocument(this, id);
|
|
5153
|
+
parseMarkdown(new TextDecoder("utf-8", { fatal: true }).decode(raw2.bytes), pathFromConceptId(id), { okfVersion: target.edition });
|
|
5154
|
+
inventory.push({ id, version: raw2.version });
|
|
5155
|
+
}
|
|
5156
|
+
if (performance.now() > deadline) throw new InventoryGuardUnsupported("inventory_scan_time_bound");
|
|
5157
|
+
compareInventoryPremises(request, target, inventory);
|
|
5158
|
+
const version2 = await mutateExact(this.#port, this.#root, pathFromConceptId(request.id), async (leaf) => {
|
|
5159
|
+
compareInventoryPremises(request, await this.#guardTarget(), inventory);
|
|
5160
|
+
const bytes = await leaf.current();
|
|
5161
|
+
if (bytes === null || versionOfBytes(bytes.toString("utf8")) !== request.expectedVersion) throw new InventoryGuardConflict("target_version");
|
|
5162
|
+
await leaf.replace(Buffer.from(raw, "utf8"));
|
|
5163
|
+
return versionOfBytes(raw);
|
|
5164
|
+
});
|
|
5165
|
+
return { version: version2, target, inventory_digest: inventoryDigest(inventory) };
|
|
5166
|
+
});
|
|
5167
|
+
}
|
|
5168
|
+
});
|
|
5169
|
+
}
|
|
5170
|
+
async #guardTarget() {
|
|
5171
|
+
const witness = await filesystemRootWitness(this.#port, this.#root);
|
|
5172
|
+
const metadata = await readRawFilesystemReserved(this, "", "index.md");
|
|
5173
|
+
const content = metadata === null ? null : new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(metadata.bytes);
|
|
5174
|
+
const edition = guardEdition(content);
|
|
5175
|
+
const after = await filesystemRootWitness(this.#port, this.#root);
|
|
5176
|
+
if (witness !== after) throw new InventoryGuardConflict("identity");
|
|
5177
|
+
const store = versionOfBytes(`${await filesystemRootMutationKey(this.#root)}:${this.#coordinator.namespace()}:${witness}`);
|
|
5178
|
+
return { contract: "inventory-guard/v1", domain: INVENTORY_GUARD_DOMAIN, adapter: "filesystem", store, edition, root_version: blobVersion(metadata.bytes) };
|
|
5179
|
+
}
|
|
4938
5180
|
/**
|
|
4939
5181
|
* The root is resolved once here: a relative root would otherwise re-resolve against the
|
|
4940
5182
|
* process's current directory on every operation, so a later `chdir` would silently move the
|
|
@@ -4943,6 +5185,7 @@ var FilesystemBackend = class _FilesystemBackend {
|
|
|
4943
5185
|
constructor(root, options = {}) {
|
|
4944
5186
|
this.#port = createNodeFilesystemIdentityPort(options.hostPolicy);
|
|
4945
5187
|
this.#root = path3.resolve(root);
|
|
5188
|
+
this.#coordinator = createFilesystemMutationCoordinator(this.#port, this.#root, options.hostPolicy);
|
|
4946
5189
|
publicationContexts.set(this, { root: this.#root, port: this.#port });
|
|
4947
5190
|
}
|
|
4948
5191
|
async read(id) {
|
|
@@ -4987,7 +5230,7 @@ var FilesystemBackend = class _FilesystemBackend {
|
|
|
4987
5230
|
assertSafeConceptId(id);
|
|
4988
5231
|
const raw = stringifyDoc(doc.frontmatter, doc.body ?? "");
|
|
4989
5232
|
const rel = pathFromConceptId(id);
|
|
4990
|
-
return mutateExact(
|
|
5233
|
+
return this.#mutateExact(rel, async (target) => {
|
|
4991
5234
|
if (options.expectedVersion !== void 0) {
|
|
4992
5235
|
const bytes = await target.current();
|
|
4993
5236
|
const current = bytes === null ? null : versionOfBytes(bytes.toString("utf8"));
|
|
@@ -5001,7 +5244,7 @@ var FilesystemBackend = class _FilesystemBackend {
|
|
|
5001
5244
|
}
|
|
5002
5245
|
async delete(id, options = {}) {
|
|
5003
5246
|
assertSafeConceptId(id);
|
|
5004
|
-
return mutateExact(
|
|
5247
|
+
return this.#mutateExact(pathFromConceptId(id), async (target) => {
|
|
5005
5248
|
const bytes = await target.current();
|
|
5006
5249
|
if (bytes === null) return false;
|
|
5007
5250
|
const current = versionOfBytes(bytes.toString("utf8"));
|
|
@@ -5065,7 +5308,7 @@ var FilesystemBackend = class _FilesystemBackend {
|
|
|
5065
5308
|
assertSafeReservedDir(dir);
|
|
5066
5309
|
assertSafeReservedFilename(name);
|
|
5067
5310
|
const rel = reservedPath(dir, name);
|
|
5068
|
-
return mutateExact(
|
|
5311
|
+
return this.#mutateExact(rel, async (target) => {
|
|
5069
5312
|
if (options.expectedVersion !== void 0) {
|
|
5070
5313
|
const bytes = await target.current();
|
|
5071
5314
|
const current = bytes === null ? null : versionOfBytes(bytes.toString("utf8"));
|
|
@@ -5087,7 +5330,7 @@ var FilesystemBackend = class _FilesystemBackend {
|
|
|
5087
5330
|
}
|
|
5088
5331
|
async writeBlob(key, bytes, _contentType, options = {}) {
|
|
5089
5332
|
assertSafeBlobKey(key);
|
|
5090
|
-
return mutateExact(
|
|
5333
|
+
return this.#mutateExact(key, async (target) => {
|
|
5091
5334
|
if (options.expectedVersion !== void 0) {
|
|
5092
5335
|
const existing = await target.current();
|
|
5093
5336
|
const current = existing === null ? null : blobVersion(existing);
|
|
@@ -5101,7 +5344,7 @@ var FilesystemBackend = class _FilesystemBackend {
|
|
|
5101
5344
|
}
|
|
5102
5345
|
async deleteBlob(key, options = {}) {
|
|
5103
5346
|
assertSafeBlobKey(key);
|
|
5104
|
-
return mutateExact(
|
|
5347
|
+
return this.#mutateExact(key, async (target) => {
|
|
5105
5348
|
const existing = await target.current();
|
|
5106
5349
|
if (existing === null) return false;
|
|
5107
5350
|
const current = blobVersion(existing);
|
|
@@ -5119,8 +5362,8 @@ var FilesystemBackend = class _FilesystemBackend {
|
|
|
5119
5362
|
}
|
|
5120
5363
|
async listBlobs(prefix) {
|
|
5121
5364
|
const files = await walkFiles(this.#port, this.#root, (name) => !name.toLowerCase().endsWith(".md"));
|
|
5122
|
-
const
|
|
5123
|
-
const filtered = prefix ?
|
|
5365
|
+
const keys2 = files.map(toPosix);
|
|
5366
|
+
const filtered = prefix ? keys2.filter((k) => k.startsWith(prefix)) : keys2;
|
|
5124
5367
|
filtered.sort(compareStorageKeys);
|
|
5125
5368
|
return filtered;
|
|
5126
5369
|
}
|
|
@@ -5134,6 +5377,35 @@ var FilesystemBackend = class _FilesystemBackend {
|
|
|
5134
5377
|
};
|
|
5135
5378
|
}
|
|
5136
5379
|
};
|
|
5380
|
+
function publicationContext(backend) {
|
|
5381
|
+
const context = publicationContexts.get(backend);
|
|
5382
|
+
if (!context) throw new InvalidInputError("Unknown filesystem backend publication source.");
|
|
5383
|
+
return context;
|
|
5384
|
+
}
|
|
5385
|
+
async function readRawFilesystemDocument(backend, id) {
|
|
5386
|
+
return readRawDocumentIn(backend, id);
|
|
5387
|
+
}
|
|
5388
|
+
async function readRawDocumentIn(backend, id, pass) {
|
|
5389
|
+
assertSafeConceptId(id);
|
|
5390
|
+
const { root, port } = publicationContext(backend);
|
|
5391
|
+
const rel = pathFromConceptId(id);
|
|
5392
|
+
const read = (handle) => readBytes(port, handle);
|
|
5393
|
+
const observed = pass ? await pass.observe(rel, read) : await observeExact(port, root, rel, read);
|
|
5394
|
+
if (observed.state === "absent") throw notFound(root, rel);
|
|
5395
|
+
const raw = new TextDecoder("utf-8", { fatal: true }).decode(observed.value);
|
|
5396
|
+
return { bytes: observed.value.slice(), version: versionOfBytes(raw) };
|
|
5397
|
+
}
|
|
5398
|
+
async function readRawFilesystemReserved(backend, dir, name) {
|
|
5399
|
+
assertSafeReservedDir(dir);
|
|
5400
|
+
assertSafeReservedFilename(name);
|
|
5401
|
+
const { root, port } = publicationContext(backend);
|
|
5402
|
+
const observed = await observeExact(port, root, reservedPath(dir, name), (handle) => readBytes(port, handle));
|
|
5403
|
+
if (observed.state === "absent") return null;
|
|
5404
|
+
return {
|
|
5405
|
+
bytes: observed.value.slice(),
|
|
5406
|
+
version: versionOfBytes(observed.value.toString("utf8"))
|
|
5407
|
+
};
|
|
5408
|
+
}
|
|
5137
5409
|
|
|
5138
5410
|
// ../core/src/bundle-ops.ts
|
|
5139
5411
|
var defaultBackendFactory;
|
|
@@ -5168,6 +5440,86 @@ async function queryEdges2(bundle, filter = {}, options = {}) {
|
|
|
5168
5440
|
// ../core/src/bundle.ts
|
|
5169
5441
|
setDefaultBackendFactory((root) => new FilesystemBackend(root));
|
|
5170
5442
|
|
|
5443
|
+
// ../core/src/managed-document-metadata.ts
|
|
5444
|
+
var MANAGED_DOCUMENT_METADATA_FIELDS = /* @__PURE__ */ new Set([
|
|
5445
|
+
"generated",
|
|
5446
|
+
"verified",
|
|
5447
|
+
"superbee_updated_by",
|
|
5448
|
+
"actor",
|
|
5449
|
+
"timestamp"
|
|
5450
|
+
]);
|
|
5451
|
+
function isManagedDocumentMetadataField(field) {
|
|
5452
|
+
return MANAGED_DOCUMENT_METADATA_FIELDS.has(field);
|
|
5453
|
+
}
|
|
5454
|
+
|
|
5455
|
+
// ../core/src/kind-deprecation.ts
|
|
5456
|
+
var problem = (field, message) => ({
|
|
5457
|
+
code: "KIND_DEPRECATION_INVALID",
|
|
5458
|
+
field,
|
|
5459
|
+
message: `${field}: ${message}`,
|
|
5460
|
+
severity: "warning"
|
|
5461
|
+
});
|
|
5462
|
+
function parseKindDeprecation(raw, kind, reserved, claimFields) {
|
|
5463
|
+
const result = { fields: [], values: {}, links: [] };
|
|
5464
|
+
const problems = [];
|
|
5465
|
+
const fail2 = (field, message) => {
|
|
5466
|
+
problems.push(problem(field, message));
|
|
5467
|
+
};
|
|
5468
|
+
const names = (value, path4) => {
|
|
5469
|
+
if (!Array.isArray(value) || value.some((v) => typeof v !== "string" || !v.trim() || v !== v.trim())) {
|
|
5470
|
+
fail2(path4, "expected a list of nonempty exact names");
|
|
5471
|
+
return [];
|
|
5472
|
+
}
|
|
5473
|
+
return [...new Set(value)];
|
|
5474
|
+
};
|
|
5475
|
+
const protectedField = (field) => reserved.includes(field) || isOkfStandardField(field) || isManagedDocumentMetadataField(field) || claimFields.includes(field);
|
|
5476
|
+
if (!isOkfRecord(raw)) fail2("deprecated", "expected a map of fields, values and links");
|
|
5477
|
+
else {
|
|
5478
|
+
for (const key of Object.keys(raw)) if (!["fields", "values", "links"].includes(key)) fail2(`deprecated.${key}`, "unknown policy coordinate");
|
|
5479
|
+
if (Object.hasOwn(raw, "fields")) result.fields = names(raw.fields, "deprecated.fields");
|
|
5480
|
+
for (const field of result.fields) {
|
|
5481
|
+
if (!kind.fields.optional.includes(field) || kind.fields.required.includes(field) || protectedField(field)) {
|
|
5482
|
+
fail2(`deprecated.fields.${field}`, "only an optional, nonstandard, nonreserved, nonclaim field can be deprecated");
|
|
5483
|
+
}
|
|
5484
|
+
}
|
|
5485
|
+
if (Object.hasOwn(raw, "values")) {
|
|
5486
|
+
if (!isOkfRecord(raw.values)) fail2("deprecated.values", "expected a field-to-values map");
|
|
5487
|
+
else for (const [field, value] of Object.entries(raw.values)) {
|
|
5488
|
+
const path4 = `deprecated.values.${field}`;
|
|
5489
|
+
const values = Array.isArray(value) && value.every((v) => ["string", "number", "boolean"].includes(typeof v)) ? [...new Set(value.map(String))] : void 0;
|
|
5490
|
+
if (!values || values.some((v) => !v.trim())) {
|
|
5491
|
+
fail2(path4, "expected a list of enum members");
|
|
5492
|
+
continue;
|
|
5493
|
+
}
|
|
5494
|
+
Object.defineProperty(result.values, field, { value: values, enumerable: true, writable: true, configurable: true });
|
|
5495
|
+
const allowed = Object.hasOwn(kind.fields.values, field) ? kind.fields.values[field] : void 0;
|
|
5496
|
+
if (protectedField(field) || ![...kind.fields.required, ...kind.fields.optional].includes(field) || !allowed || values.some((v) => !allowed.includes(v)) || kind.fields.types?.[field] === "https-url-list") {
|
|
5497
|
+
fail2(path4, "expected members of a declared, nonstandard, nonclaim vocabulary");
|
|
5498
|
+
}
|
|
5499
|
+
const terminal = Object.hasOwn(kind.fields.terminal, field) ? kind.fields.terminal[field] : [];
|
|
5500
|
+
if (values.some((v) => terminal.includes(v))) fail2(path4, "terminal members require a separate migration");
|
|
5501
|
+
if (kind.fields.required.includes(field) && allowed && !allowed.some((v) => !values.includes(v))) fail2(path4, "a required field must retain an active member");
|
|
5502
|
+
}
|
|
5503
|
+
}
|
|
5504
|
+
if (Object.hasOwn(raw, "links")) result.links = names(raw.links, "deprecated.links");
|
|
5505
|
+
for (const label of result.links) if (!kind.links || !Object.hasOwn(kind.links, label)) fail2(`deprecated.links.${label}`, "expected an existing outbound label");
|
|
5506
|
+
}
|
|
5507
|
+
if (problems.length) {
|
|
5508
|
+
result.problems = problems;
|
|
5509
|
+
result.raw = structuredClone(raw);
|
|
5510
|
+
}
|
|
5511
|
+
return result;
|
|
5512
|
+
}
|
|
5513
|
+
function kindDeprecationProblems(kind, registry) {
|
|
5514
|
+
const problems = [...kind.deprecated?.problems ?? []];
|
|
5515
|
+
for (const label of kind.deprecated?.links ?? []) {
|
|
5516
|
+
if ([...registry?.kinds.values() ?? [kind]].some((k) => k.expectsInbound && Object.hasOwn(k.expectsInbound, label))) {
|
|
5517
|
+
problems.push(problem(`deprecated.links.${label}`, "the admitted registry still declares an inbound expectation for this label"));
|
|
5518
|
+
}
|
|
5519
|
+
}
|
|
5520
|
+
return problems;
|
|
5521
|
+
}
|
|
5522
|
+
|
|
5171
5523
|
// ../core/src/kinds.ts
|
|
5172
5524
|
var CONVENTIONS_PREFIX = "conventions/";
|
|
5173
5525
|
var CONVENTION_TYPE = "Convention";
|
|
@@ -5231,6 +5583,7 @@ function buildKindRegistry(docs, initialWarnings = [], options = {}) {
|
|
|
5231
5583
|
}
|
|
5232
5584
|
accepted.set(kind.governs, kind);
|
|
5233
5585
|
}
|
|
5586
|
+
for (const kind of accepted.values()) warnings.push(...kindDeprecationProblems(kind, { kinds: accepted, warnings: [] }).filter((w) => !warnings.includes(w)));
|
|
5234
5587
|
const kinds = /* @__PURE__ */ new Map();
|
|
5235
5588
|
for (const kind of [...accepted.values()].sort(compareReadingOrder)) kinds.set(kind.governs, kind);
|
|
5236
5589
|
return { kinds, warnings };
|
|
@@ -5244,9 +5597,9 @@ function compareReadingOrder(a, b) {
|
|
|
5244
5597
|
var PROGRESS_STATUS_FIELD = "progress_status";
|
|
5245
5598
|
var SUPERBEE_PROGRESS_STATUS_FIELD = "superbee_progress_status";
|
|
5246
5599
|
function progressStatusStorageField(okfVersion) {
|
|
5247
|
-
const
|
|
5248
|
-
if (
|
|
5249
|
-
if (
|
|
5600
|
+
const version2 = okfVersion?.trim() || "0.1";
|
|
5601
|
+
if (version2 === "0.1") return "status";
|
|
5602
|
+
if (version2 === "0.2") return SUPERBEE_PROGRESS_STATUS_FIELD;
|
|
5250
5603
|
return void 0;
|
|
5251
5604
|
}
|
|
5252
5605
|
function declaresField(kind, field) {
|
|
@@ -5269,6 +5622,19 @@ function resolveKindFieldCoordinate(okfVersion, kind, field) {
|
|
|
5269
5622
|
if (field === PROGRESS_STATUS_FIELD && progress) return progress;
|
|
5270
5623
|
return void 0;
|
|
5271
5624
|
}
|
|
5625
|
+
function claimCoordinates(okfVersion, kind) {
|
|
5626
|
+
if (!kind.claim) return void 0;
|
|
5627
|
+
const resolve = (field) => field === void 0 ? void 0 : resolveKindFieldCoordinate(okfVersion, kind, field)?.storageField;
|
|
5628
|
+
const ownerField = resolve(kind.claim.ownerField);
|
|
5629
|
+
const stateField = resolve(kind.claim.stateField);
|
|
5630
|
+
const fields = [...new Set([ownerField, stateField].filter((f) => f !== void 0))];
|
|
5631
|
+
if (fields.length === 0) return void 0;
|
|
5632
|
+
return {
|
|
5633
|
+
...ownerField !== void 0 ? { ownerField } : {},
|
|
5634
|
+
...stateField !== void 0 ? { stateField } : {},
|
|
5635
|
+
fields
|
|
5636
|
+
};
|
|
5637
|
+
}
|
|
5272
5638
|
function readKindField(okfVersion, kind, frontmatter2, field) {
|
|
5273
5639
|
const coordinate = resolveKindFieldCoordinate(okfVersion, kind, field);
|
|
5274
5640
|
return coordinate ? frontmatter2[coordinate.storageField] : void 0;
|
|
@@ -5289,11 +5655,11 @@ function isPlainObject(value) {
|
|
|
5289
5655
|
const prototype = Object.getPrototypeOf(value);
|
|
5290
5656
|
return prototype === Object.prototype || prototype === null;
|
|
5291
5657
|
}
|
|
5292
|
-
function hasOwn(
|
|
5293
|
-
return Object.prototype.hasOwnProperty.call(
|
|
5658
|
+
function hasOwn(record2, key) {
|
|
5659
|
+
return Object.prototype.hasOwnProperty.call(record2, key);
|
|
5294
5660
|
}
|
|
5295
|
-
function setOwn(
|
|
5296
|
-
Object.defineProperty(
|
|
5661
|
+
function setOwn(record2, key, value) {
|
|
5662
|
+
Object.defineProperty(record2, key, { value, enumerable: true, configurable: true, writable: true });
|
|
5297
5663
|
}
|
|
5298
5664
|
function isScalar(value) {
|
|
5299
5665
|
return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
@@ -5785,6 +6151,10 @@ function parseConventionDoc(doc, options = {}) {
|
|
|
5785
6151
|
if (browseCollapsed !== void 0) kind.browseCollapsed = browseCollapsed;
|
|
5786
6152
|
if (order !== void 0) kind.order = order;
|
|
5787
6153
|
if (claim !== void 0) kind.claim = claim;
|
|
6154
|
+
if (Object.hasOwn(fm, "deprecated")) {
|
|
6155
|
+
kind.deprecated = parseKindDeprecation(fm.deprecated, kind, RESERVED_KIND_FIELD_NAMES, claimCoordinates(options.okfVersion, kind)?.fields ?? []);
|
|
6156
|
+
warnings.push(...kind.deprecated.problems ?? []);
|
|
6157
|
+
}
|
|
5788
6158
|
return {
|
|
5789
6159
|
ok: true,
|
|
5790
6160
|
kind,
|
|
@@ -6314,8 +6684,8 @@ var BridgeService = class {
|
|
|
6314
6684
|
if (!after) return this.reload(launchId, "the View changed while its subscription was polled");
|
|
6315
6685
|
const changes = [];
|
|
6316
6686
|
const removed = [];
|
|
6317
|
-
for (const [id,
|
|
6318
|
-
if (subscription.baseline.get(id) !==
|
|
6687
|
+
for (const [id, version2] of next) {
|
|
6688
|
+
if (subscription.baseline.get(id) !== version2) changes.push({ id, version: version2 });
|
|
6319
6689
|
}
|
|
6320
6690
|
for (const id of subscription.baseline.keys()) {
|
|
6321
6691
|
if (!next.has(id)) removed.push(id);
|