@fedify/vocab 2.0.0-dev.237 → 2.0.0-dev.279
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/deno.json +9 -2
- package/dist/actor.test.js +2 -2
- package/dist/{deno-DZVL5ko5.js → deno-y1THYur-.js} +8 -2
- package/dist/lookup.test.js +2 -2
- package/dist/mod.cjs +13 -7
- package/dist/mod.js +13 -7
- package/dist/type.test.js +1 -1
- package/dist/{vocab-BCNCvjVX.js → vocab-fPKUeh35.js} +5 -5
- package/dist/vocab.test.js +1 -1
- package/package.json +10 -7
- package/scripts/codegen.ts +147 -11
package/deno.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fedify/vocab",
|
|
3
|
-
"version": "2.0.0-dev.
|
|
3
|
+
"version": "2.0.0-dev.279+ce1bdc22",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./src/mod.ts"
|
|
@@ -23,9 +23,16 @@
|
|
|
23
23
|
"src/*.yaml",
|
|
24
24
|
"!src/vocab.ts"
|
|
25
25
|
],
|
|
26
|
+
"publish": {
|
|
27
|
+
"exclude": [
|
|
28
|
+
"**/*.test.ts",
|
|
29
|
+
"tsdown.config.ts",
|
|
30
|
+
"scripts/"
|
|
31
|
+
]
|
|
32
|
+
},
|
|
26
33
|
"tasks": {
|
|
27
34
|
"check": "deno fmt --check && deno lint && deno check src/*.ts",
|
|
28
|
-
"compile": "deno run --allow-read --allow-write --allow-env --
|
|
35
|
+
"compile": "deno run --allow-read --allow-write --allow-env --allow-run scripts/codegen.ts",
|
|
29
36
|
"test": "deno test --allow-read --allow-write --allow-env --unstable-kv --trace-leaks --parallel"
|
|
30
37
|
}
|
|
31
38
|
}
|
package/dist/actor.test.js
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
4
|
|
|
5
5
|
import { __export } from "./chunk-BeeFIeNn.js";
|
|
6
|
-
import { Application, Group, Organization, Person, Service, test } from "./vocab-
|
|
7
|
-
import { deno_default, esm_default } from "./deno-
|
|
6
|
+
import { Application, Group, Organization, Person, Service, test } from "./vocab-fPKUeh35.js";
|
|
7
|
+
import { deno_default, esm_default } from "./deno-y1THYur-.js";
|
|
8
8
|
import { getTypeId } from "./type-Dnf0m2yO.js";
|
|
9
9
|
import { SpanStatusCode, trace } from "@opentelemetry/api";
|
|
10
10
|
import { deepStrictEqual, ok, rejects, strictEqual, throws } from "node:assert/strict";
|
|
@@ -1240,7 +1240,7 @@ var esm_default = FetchMock_default;
|
|
|
1240
1240
|
//#endregion
|
|
1241
1241
|
//#region deno.json
|
|
1242
1242
|
var name = "@fedify/vocab";
|
|
1243
|
-
var version = "2.0.0-dev.
|
|
1243
|
+
var version = "2.0.0-dev.279+ce1bdc22";
|
|
1244
1244
|
var license = "MIT";
|
|
1245
1245
|
var exports = { ".": "./src/mod.ts" };
|
|
1246
1246
|
var description = "Vocabularies library for @fedify/fedify";
|
|
@@ -1261,9 +1261,14 @@ var exclude = [
|
|
|
1261
1261
|
"src/*.yaml",
|
|
1262
1262
|
"!src/vocab.ts"
|
|
1263
1263
|
];
|
|
1264
|
+
var publish = { "exclude": [
|
|
1265
|
+
"**/*.test.ts",
|
|
1266
|
+
"tsdown.config.ts",
|
|
1267
|
+
"scripts/"
|
|
1268
|
+
] };
|
|
1264
1269
|
var tasks = {
|
|
1265
1270
|
"check": "deno fmt --check && deno lint && deno check src/*.ts",
|
|
1266
|
-
"compile": "deno run --allow-read --allow-write --allow-env --
|
|
1271
|
+
"compile": "deno run --allow-read --allow-write --allow-env --allow-run scripts/codegen.ts",
|
|
1267
1272
|
"test": "deno test --allow-read --allow-write --allow-env --unstable-kv --trace-leaks --parallel"
|
|
1268
1273
|
};
|
|
1269
1274
|
var deno_default = {
|
|
@@ -1275,6 +1280,7 @@ var deno_default = {
|
|
|
1275
1280
|
author,
|
|
1276
1281
|
imports,
|
|
1277
1282
|
exclude,
|
|
1283
|
+
publish,
|
|
1278
1284
|
tasks
|
|
1279
1285
|
};
|
|
1280
1286
|
|
package/dist/lookup.test.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import { Temporal } from "@js-temporal/polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
4
|
|
|
5
|
-
import { Collection, Note, Object as Object$1, Person, createTestTracerProvider, getDocumentLoader, mockDocumentLoader, test } from "./vocab-
|
|
6
|
-
import { deno_default, esm_default } from "./deno-
|
|
5
|
+
import { Collection, Note, Object as Object$1, Person, createTestTracerProvider, getDocumentLoader, mockDocumentLoader, test } from "./vocab-fPKUeh35.js";
|
|
6
|
+
import { deno_default, esm_default } from "./deno-y1THYur-.js";
|
|
7
7
|
import { getTypeId } from "./type-Dnf0m2yO.js";
|
|
8
8
|
import { assertInstanceOf } from "./utils-Dm0Onkcz.js";
|
|
9
9
|
import { getLogger } from "@logtape/logtape";
|
package/dist/mod.cjs
CHANGED
|
@@ -41,7 +41,7 @@ const es_toolkit = __toESM(require("es-toolkit"));
|
|
|
41
41
|
|
|
42
42
|
//#region deno.json
|
|
43
43
|
var name$1 = "@fedify/vocab";
|
|
44
|
-
var version$1 = "2.0.0-dev.
|
|
44
|
+
var version$1 = "2.0.0-dev.279+ce1bdc22";
|
|
45
45
|
var license$1 = "MIT";
|
|
46
46
|
var exports$2 = { ".": "./src/mod.ts" };
|
|
47
47
|
var description$1 = "Vocabularies library for @fedify/fedify";
|
|
@@ -62,9 +62,14 @@ var exclude$1 = [
|
|
|
62
62
|
"src/*.yaml",
|
|
63
63
|
"!src/vocab.ts"
|
|
64
64
|
];
|
|
65
|
+
var publish$1 = { "exclude": [
|
|
66
|
+
"**/*.test.ts",
|
|
67
|
+
"tsdown.config.ts",
|
|
68
|
+
"scripts/"
|
|
69
|
+
] };
|
|
65
70
|
var tasks$1 = {
|
|
66
71
|
"check": "deno fmt --check && deno lint && deno check src/*.ts",
|
|
67
|
-
"compile": "deno run --allow-read --allow-write --allow-env --
|
|
72
|
+
"compile": "deno run --allow-read --allow-write --allow-env --allow-run scripts/codegen.ts",
|
|
68
73
|
"test": "deno test --allow-read --allow-write --allow-env --unstable-kv --trace-leaks --parallel"
|
|
69
74
|
};
|
|
70
75
|
var deno_default = {
|
|
@@ -76,6 +81,7 @@ var deno_default = {
|
|
|
76
81
|
author: author$1,
|
|
77
82
|
imports: imports$1,
|
|
78
83
|
exclude: exclude$1,
|
|
84
|
+
publish: publish$1,
|
|
79
85
|
tasks: tasks$1
|
|
80
86
|
};
|
|
81
87
|
|
|
@@ -4356,7 +4362,7 @@ const preloadedContexts = {
|
|
|
4356
4362
|
};
|
|
4357
4363
|
var contexts_default = preloadedContexts;
|
|
4358
4364
|
var name = "@fedify/vocab-runtime";
|
|
4359
|
-
var version = "2.0.0-dev.
|
|
4365
|
+
var version = "2.0.0-dev.279+ce1bdc22";
|
|
4360
4366
|
var license = "MIT";
|
|
4361
4367
|
var exports$1 = { ".": "./src/mod.ts" };
|
|
4362
4368
|
var description = "Runtime library for @fedify/vocab";
|
|
@@ -4374,7 +4380,7 @@ var imports = {
|
|
|
4374
4380
|
"pkijs": "npm:pkijs@^3.2.5"
|
|
4375
4381
|
};
|
|
4376
4382
|
var exclude = ["dist", "node_modules"];
|
|
4377
|
-
var publish = { "exclude": ["**/*.test.ts"] };
|
|
4383
|
+
var publish = { "exclude": ["**/*.test.ts", "tsdown.config.ts"] };
|
|
4378
4384
|
var tasks = {
|
|
4379
4385
|
"check": "deno fmt --check && deno lint && deno check src/*.ts",
|
|
4380
4386
|
"test": "deno test"
|
|
@@ -4796,7 +4802,7 @@ async function getRemoteDocument(url, response, fetch$1) {
|
|
|
4796
4802
|
* Creates a JSON-LD document loader that utilizes the browser's `fetch` API.
|
|
4797
4803
|
*
|
|
4798
4804
|
* The created loader preloads the below frequently used contexts by default
|
|
4799
|
-
* (unless `options.
|
|
4805
|
+
* (unless `options.skipPreloadedContexts` is set to `true`):
|
|
4800
4806
|
*
|
|
4801
4807
|
* - <https://www.w3.org/ns/activitystreams>
|
|
4802
4808
|
* - <https://w3id.org/security/v1>
|
|
@@ -5319,8 +5325,8 @@ var LanguageString = class extends String {
|
|
|
5319
5325
|
/**
|
|
5320
5326
|
* Constructs a new `LanguageString`.
|
|
5321
5327
|
* @param value A string value written in the given language.
|
|
5322
|
-
* @param
|
|
5323
|
-
*
|
|
5328
|
+
* @param language The language of the string. If a string is given, it will
|
|
5329
|
+
* be parsed as a `Intl.Locale` object.
|
|
5324
5330
|
*/
|
|
5325
5331
|
constructor(value, language) {
|
|
5326
5332
|
super(value);
|
package/dist/mod.js
CHANGED
|
@@ -18,7 +18,7 @@ import { delay } from "es-toolkit";
|
|
|
18
18
|
|
|
19
19
|
//#region deno.json
|
|
20
20
|
var name$1 = "@fedify/vocab";
|
|
21
|
-
var version$1 = "2.0.0-dev.
|
|
21
|
+
var version$1 = "2.0.0-dev.279+ce1bdc22";
|
|
22
22
|
var license$1 = "MIT";
|
|
23
23
|
var exports$1 = { ".": "./src/mod.ts" };
|
|
24
24
|
var description$1 = "Vocabularies library for @fedify/fedify";
|
|
@@ -39,9 +39,14 @@ var exclude$1 = [
|
|
|
39
39
|
"src/*.yaml",
|
|
40
40
|
"!src/vocab.ts"
|
|
41
41
|
];
|
|
42
|
+
var publish$1 = { "exclude": [
|
|
43
|
+
"**/*.test.ts",
|
|
44
|
+
"tsdown.config.ts",
|
|
45
|
+
"scripts/"
|
|
46
|
+
] };
|
|
42
47
|
var tasks$1 = {
|
|
43
48
|
"check": "deno fmt --check && deno lint && deno check src/*.ts",
|
|
44
|
-
"compile": "deno run --allow-read --allow-write --allow-env --
|
|
49
|
+
"compile": "deno run --allow-read --allow-write --allow-env --allow-run scripts/codegen.ts",
|
|
45
50
|
"test": "deno test --allow-read --allow-write --allow-env --unstable-kv --trace-leaks --parallel"
|
|
46
51
|
};
|
|
47
52
|
var deno_default = {
|
|
@@ -53,6 +58,7 @@ var deno_default = {
|
|
|
53
58
|
author: author$1,
|
|
54
59
|
imports: imports$1,
|
|
55
60
|
exclude: exclude$1,
|
|
61
|
+
publish: publish$1,
|
|
56
62
|
tasks: tasks$1
|
|
57
63
|
};
|
|
58
64
|
|
|
@@ -4333,7 +4339,7 @@ const preloadedContexts = {
|
|
|
4333
4339
|
};
|
|
4334
4340
|
var contexts_default = preloadedContexts;
|
|
4335
4341
|
var name = "@fedify/vocab-runtime";
|
|
4336
|
-
var version = "2.0.0-dev.
|
|
4342
|
+
var version = "2.0.0-dev.279+ce1bdc22";
|
|
4337
4343
|
var license = "MIT";
|
|
4338
4344
|
var exports = { ".": "./src/mod.ts" };
|
|
4339
4345
|
var description = "Runtime library for @fedify/vocab";
|
|
@@ -4351,7 +4357,7 @@ var imports = {
|
|
|
4351
4357
|
"pkijs": "npm:pkijs@^3.2.5"
|
|
4352
4358
|
};
|
|
4353
4359
|
var exclude = ["dist", "node_modules"];
|
|
4354
|
-
var publish = { "exclude": ["**/*.test.ts"] };
|
|
4360
|
+
var publish = { "exclude": ["**/*.test.ts", "tsdown.config.ts"] };
|
|
4355
4361
|
var tasks = {
|
|
4356
4362
|
"check": "deno fmt --check && deno lint && deno check src/*.ts",
|
|
4357
4363
|
"test": "deno test"
|
|
@@ -4773,7 +4779,7 @@ async function getRemoteDocument(url, response, fetch$1) {
|
|
|
4773
4779
|
* Creates a JSON-LD document loader that utilizes the browser's `fetch` API.
|
|
4774
4780
|
*
|
|
4775
4781
|
* The created loader preloads the below frequently used contexts by default
|
|
4776
|
-
* (unless `options.
|
|
4782
|
+
* (unless `options.skipPreloadedContexts` is set to `true`):
|
|
4777
4783
|
*
|
|
4778
4784
|
* - <https://www.w3.org/ns/activitystreams>
|
|
4779
4785
|
* - <https://w3id.org/security/v1>
|
|
@@ -5296,8 +5302,8 @@ var LanguageString = class extends String {
|
|
|
5296
5302
|
/**
|
|
5297
5303
|
* Constructs a new `LanguageString`.
|
|
5298
5304
|
* @param value A string value written in the given language.
|
|
5299
|
-
* @param
|
|
5300
|
-
*
|
|
5305
|
+
* @param language The language of the string. If a string is given, it will
|
|
5306
|
+
* be parsed as a `Intl.Locale` object.
|
|
5301
5307
|
*/
|
|
5302
5308
|
constructor(value, language) {
|
|
5303
5309
|
super(value);
|
package/dist/type.test.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { Temporal } from "@js-temporal/polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
4
|
|
|
5
|
-
import { Person, test } from "./vocab-
|
|
5
|
+
import { Person, test } from "./vocab-fPKUeh35.js";
|
|
6
6
|
import { getTypeId } from "./type-Dnf0m2yO.js";
|
|
7
7
|
import { deepStrictEqual } from "node:assert/strict";
|
|
8
8
|
|
|
@@ -10561,7 +10561,7 @@ const preloadedContexts = {
|
|
|
10561
10561
|
};
|
|
10562
10562
|
var contexts_default = preloadedContexts;
|
|
10563
10563
|
var name = "@fedify/vocab-runtime";
|
|
10564
|
-
var version = "2.0.0-dev.
|
|
10564
|
+
var version = "2.0.0-dev.279+ce1bdc22";
|
|
10565
10565
|
var license = "MIT";
|
|
10566
10566
|
var exports$1 = { ".": "./src/mod.ts" };
|
|
10567
10567
|
var description = "Runtime library for @fedify/vocab";
|
|
@@ -10579,7 +10579,7 @@ var imports = {
|
|
|
10579
10579
|
"pkijs": "npm:pkijs@^3.2.5"
|
|
10580
10580
|
};
|
|
10581
10581
|
var exclude = ["dist", "node_modules"];
|
|
10582
|
-
var publish = { "exclude": ["**/*.test.ts"] };
|
|
10582
|
+
var publish = { "exclude": ["**/*.test.ts", "tsdown.config.ts"] };
|
|
10583
10583
|
var tasks = {
|
|
10584
10584
|
"check": "deno fmt --check && deno lint && deno check src/*.ts",
|
|
10585
10585
|
"test": "deno test"
|
|
@@ -11001,7 +11001,7 @@ async function getRemoteDocument(url, response, fetch$1) {
|
|
|
11001
11001
|
* Creates a JSON-LD document loader that utilizes the browser's `fetch` API.
|
|
11002
11002
|
*
|
|
11003
11003
|
* The created loader preloads the below frequently used contexts by default
|
|
11004
|
-
* (unless `options.
|
|
11004
|
+
* (unless `options.skipPreloadedContexts` is set to `true`):
|
|
11005
11005
|
*
|
|
11006
11006
|
* - <https://www.w3.org/ns/activitystreams>
|
|
11007
11007
|
* - <https://w3id.org/security/v1>
|
|
@@ -11524,8 +11524,8 @@ var LanguageString = class extends String {
|
|
|
11524
11524
|
/**
|
|
11525
11525
|
* Constructs a new `LanguageString`.
|
|
11526
11526
|
* @param value A string value written in the given language.
|
|
11527
|
-
* @param
|
|
11528
|
-
*
|
|
11527
|
+
* @param language The language of the string. If a string is given, it will
|
|
11528
|
+
* be parsed as a `Intl.Locale` object.
|
|
11529
11529
|
*/
|
|
11530
11530
|
constructor(value, language) {
|
|
11531
11531
|
super(value);
|
package/dist/vocab.test.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { Temporal } from "@js-temporal/polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
4
|
|
|
5
|
-
import { Activity, Announce, Collection, Create, CryptographicKey, Follow, Hashtag, LanguageString, Link, Note, Object as Object$1, OrderedCollectionPage, Person, Place, Question, Source, decodeMultibase, mockDocumentLoader, test, vocab_exports } from "./vocab-
|
|
5
|
+
import { Activity, Announce, Collection, Create, CryptographicKey, Follow, Hashtag, LanguageString, Link, Note, Object as Object$1, OrderedCollectionPage, Person, Place, Question, Source, decodeMultibase, mockDocumentLoader, test, vocab_exports } from "./vocab-fPKUeh35.js";
|
|
6
6
|
import { assertInstanceOf } from "./utils-Dm0Onkcz.js";
|
|
7
7
|
import { deepStrictEqual, notDeepStrictEqual, ok, rejects, throws } from "node:assert/strict";
|
|
8
8
|
import { pascalCase } from "es-toolkit";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fedify/vocab",
|
|
3
|
-
"version": "2.0.0-dev.
|
|
3
|
+
"version": "2.0.0-dev.279+ce1bdc22",
|
|
4
4
|
"homepage": "https://fedify.dev/",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -47,8 +47,8 @@
|
|
|
47
47
|
"jsonld": "^9.0.0",
|
|
48
48
|
"multicodec": "^3.2.1",
|
|
49
49
|
"pkijs": "^3.3.3",
|
|
50
|
-
"@fedify/vocab-tools": "2.0.0-dev.
|
|
51
|
-
"@fedify/webfinger": "2.0.0-dev.
|
|
50
|
+
"@fedify/vocab-tools": "2.0.0-dev.279+ce1bdc22",
|
|
51
|
+
"@fedify/webfinger": "2.0.0-dev.279+ce1bdc22"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@types/node": "^22.17.0",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"tsdown": "^0.12.9",
|
|
58
58
|
"typescript": "^5.9.3",
|
|
59
59
|
"@fedify/fixture": "2.0.0",
|
|
60
|
-
"@fedify/vocab-runtime": "2.0.0-dev.
|
|
60
|
+
"@fedify/vocab-runtime": "2.0.0-dev.279+ce1bdc22"
|
|
61
61
|
},
|
|
62
62
|
"keywords": [
|
|
63
63
|
"Fedify",
|
|
@@ -71,9 +71,12 @@
|
|
|
71
71
|
},
|
|
72
72
|
"license": "MIT",
|
|
73
73
|
"scripts": {
|
|
74
|
-
"build": "tsdown",
|
|
74
|
+
"build:self": "deno task compile && tsdown",
|
|
75
|
+
"build": "pnpm --filter @fedify/vocab... run build:self",
|
|
75
76
|
"prepublish": "pnpm build",
|
|
76
|
-
"
|
|
77
|
-
"test
|
|
77
|
+
"pretest": "pnpm build",
|
|
78
|
+
"test": "cd dist/ && node --test",
|
|
79
|
+
"pretest:bun": "pnpm build",
|
|
80
|
+
"test:bun": "cd dist/ && bun test --timeout 60000"
|
|
78
81
|
}
|
|
79
82
|
}
|
package/scripts/codegen.ts
CHANGED
|
@@ -1,18 +1,154 @@
|
|
|
1
|
+
import $ from "@david/dax";
|
|
2
|
+
import type { Path } from "@david/dax";
|
|
1
3
|
import { generateVocab } from "@fedify/vocab-tools";
|
|
2
|
-
import { rename } from "node:fs/promises";
|
|
3
|
-
import { dirname, join } from "node:path";
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
const LOCK_STALE_MS = 5 * 60 * 1000; // 5 minutes
|
|
6
|
+
const LOCK_RETRY_MS = 100;
|
|
7
|
+
const LOCK_TIMEOUT_MS = 60 * 1000; // 1 minute
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Get the latest mtime from all YAML files in the schema directory.
|
|
11
|
+
*/
|
|
12
|
+
async function getLatestSourceMtime(schemaDir: Path): Promise<number> {
|
|
13
|
+
let latestMtime = 0;
|
|
14
|
+
for await (const entry of schemaDir.readDir()) {
|
|
15
|
+
if (!entry.isFile) continue;
|
|
16
|
+
if (!entry.name.match(/\.ya?ml$/i)) continue;
|
|
17
|
+
if (entry.name === "schema.yaml") continue;
|
|
18
|
+
const fileStat = await schemaDir.join(entry.name).stat();
|
|
19
|
+
if (fileStat?.mtime && fileStat.mtime.getTime() > latestMtime) {
|
|
20
|
+
latestMtime = fileStat.mtime.getTime();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return latestMtime;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Check if the generated file is up to date compared to source files.
|
|
28
|
+
*/
|
|
29
|
+
async function isUpToDate(
|
|
30
|
+
schemaDir: Path,
|
|
31
|
+
generatedPath: Path,
|
|
32
|
+
): Promise<boolean> {
|
|
33
|
+
try {
|
|
34
|
+
const [sourceMtime, generatedStat] = await Promise.all([
|
|
35
|
+
getLatestSourceMtime(schemaDir),
|
|
36
|
+
generatedPath.stat(),
|
|
37
|
+
]);
|
|
38
|
+
if (!generatedStat?.mtime) return false;
|
|
39
|
+
return generatedStat.mtime.getTime() >= sourceMtime;
|
|
40
|
+
} catch {
|
|
41
|
+
// If generated file doesn't exist, it's not up to date
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
interface Lock {
|
|
47
|
+
release(): Promise<void>;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Acquire a directory-based lock. mkdir is atomic on POSIX systems.
|
|
52
|
+
*/
|
|
53
|
+
async function acquireLock(lockPath: Path): Promise<Lock> {
|
|
54
|
+
const startTime = Date.now();
|
|
55
|
+
|
|
56
|
+
while (true) {
|
|
57
|
+
try {
|
|
58
|
+
// Use Deno.mkdir directly because dax's mkdir() is recursive by default
|
|
59
|
+
await Deno.mkdir(lockPath.toString());
|
|
60
|
+
// Write PID and timestamp for stale lock detection
|
|
61
|
+
const infoPath = lockPath.join("info");
|
|
62
|
+
await infoPath.writeJsonPretty({ pid: Deno.pid, timestamp: Date.now() });
|
|
63
|
+
return {
|
|
64
|
+
async release() {
|
|
65
|
+
try {
|
|
66
|
+
await lockPath.remove({ recursive: true });
|
|
67
|
+
} catch {
|
|
68
|
+
// Ignore errors during cleanup
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
} catch (e) {
|
|
73
|
+
if (!(e instanceof Deno.errors.AlreadyExists)) {
|
|
74
|
+
throw e;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Check if lock is stale
|
|
78
|
+
try {
|
|
79
|
+
const infoPath = lockPath.join("info");
|
|
80
|
+
const infoStat = await infoPath.stat();
|
|
81
|
+
if (
|
|
82
|
+
infoStat?.mtime &&
|
|
83
|
+
Date.now() - infoStat.mtime.getTime() > LOCK_STALE_MS
|
|
84
|
+
) {
|
|
85
|
+
console.warn("Removing stale lock:", lockPath.toString());
|
|
86
|
+
await lockPath.remove({ recursive: true });
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
} catch {
|
|
90
|
+
// If we can't read the info file, try to remove the lock
|
|
91
|
+
try {
|
|
92
|
+
await lockPath.remove({ recursive: true });
|
|
93
|
+
continue;
|
|
94
|
+
} catch {
|
|
95
|
+
// Ignore
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Check timeout
|
|
100
|
+
if (Date.now() - startTime > LOCK_TIMEOUT_MS) {
|
|
101
|
+
throw new Error(`Timeout waiting for lock: ${lockPath}`);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Wait and retry
|
|
105
|
+
await $.sleep(LOCK_RETRY_MS);
|
|
106
|
+
}
|
|
9
107
|
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
async function codegen() {
|
|
111
|
+
const scriptsDir = $.path(import.meta.dirname!);
|
|
112
|
+
const packageDir = scriptsDir.parent()!;
|
|
113
|
+
const schemaDir = packageDir.join("src");
|
|
114
|
+
const realPath = schemaDir.join("vocab.ts");
|
|
115
|
+
const lockPath = packageDir.join(".vocab-codegen.lock");
|
|
116
|
+
|
|
117
|
+
// Acquire lock to prevent concurrent codegen
|
|
118
|
+
const lock = await acquireLock(lockPath);
|
|
119
|
+
try {
|
|
120
|
+
// Check if regeneration is needed (after acquiring lock)
|
|
121
|
+
if (await isUpToDate(schemaDir, realPath)) {
|
|
122
|
+
$.log("vocab.ts is up to date, skipping codegen");
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
13
125
|
|
|
14
|
-
|
|
15
|
-
|
|
126
|
+
$.logStep("Generating", "vocab.ts...");
|
|
127
|
+
|
|
128
|
+
// Generate to a temporary file first
|
|
129
|
+
const generatedPath = schemaDir.join(`vocab-${crypto.randomUUID()}.ts`);
|
|
130
|
+
try {
|
|
131
|
+
await generateVocab(schemaDir.toString(), generatedPath.toString());
|
|
132
|
+
await generatedPath.rename(realPath);
|
|
133
|
+
} catch (e) {
|
|
134
|
+
// Clean up temp file on error
|
|
135
|
+
await generatedPath.remove().catch(() => {});
|
|
136
|
+
throw e;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
$.logStep("Formatting", "vocab.ts...");
|
|
140
|
+
await $`deno fmt ${realPath}`;
|
|
141
|
+
|
|
142
|
+
$.logStep("Caching", "vocab.ts...");
|
|
143
|
+
await $`deno cache ${realPath}`;
|
|
144
|
+
|
|
145
|
+
$.logStep("Type checking", "vocab.ts...");
|
|
146
|
+
await $`deno check ${realPath}`;
|
|
147
|
+
|
|
148
|
+
$.logStep("Codegen", "completed successfully");
|
|
149
|
+
} finally {
|
|
150
|
+
await lock.release();
|
|
151
|
+
}
|
|
16
152
|
}
|
|
17
153
|
|
|
18
154
|
if (import.meta.main) {
|