@inlang/sdk 0.34.7 → 0.34.9
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/api.d.ts +1 -1
- package/dist/createMessageLintReportsQuery.d.ts +5 -1
- package/dist/createMessageLintReportsQuery.d.ts.map +1 -1
- package/dist/createMessageLintReportsQuery.js +12 -3
- package/dist/createMessagesQuery.d.ts.map +1 -1
- package/dist/createMessagesQuery.js +7 -9
- package/dist/createNewProject.d.ts +0 -5
- package/dist/createNewProject.d.ts.map +1 -1
- package/dist/createNewProject.js +0 -5
- package/dist/createNodeishFsWithWatcher.d.ts +3 -2
- package/dist/createNodeishFsWithWatcher.d.ts.map +1 -1
- package/dist/createNodeishFsWithWatcher.js +12 -1
- package/dist/createNodeishFsWithWatcher.test.js +1 -3
- package/dist/persistence/filelock/acquireFileLock.d.ts.map +1 -1
- package/dist/persistence/filelock/acquireFileLock.js +2 -2
- package/dist/persistence/filelock/releaseLock.js +1 -1
- package/package.json +2 -2
- package/src/api.ts +1 -1
- package/src/createMessageLintReportsQuery.ts +13 -5
- package/src/createMessagesQuery.ts +8 -10
- package/src/createNewProject.ts +0 -5
- package/src/createNodeishFsWithWatcher.test.ts +1 -4
- package/src/createNodeishFsWithWatcher.ts +16 -3
- package/src/persistence/filelock/acquireFileLock.ts +4 -2
- package/src/persistence/filelock/releaseLock.ts +1 -1
package/dist/api.d.ts
CHANGED
|
@@ -48,7 +48,7 @@ export type InlangProject = {
|
|
|
48
48
|
};
|
|
49
49
|
/**
|
|
50
50
|
* WIP template for async V2 crud interfaces
|
|
51
|
-
* E.g. `project.messageBundles.get({ id: "..." })`
|
|
51
|
+
* E.g. `await project.messageBundles.get({ id: "..." })`
|
|
52
52
|
**/
|
|
53
53
|
interface Query<T> {
|
|
54
54
|
get: (args: unknown) => Promise<T>;
|
|
@@ -2,7 +2,11 @@ import type { InlangProject, InstalledMessageLintRule, MessageQueryApi } from ".
|
|
|
2
2
|
import type { ProjectSettings } from "@inlang/project-settings";
|
|
3
3
|
import type { resolveModules } from "./resolve-modules/index.js";
|
|
4
4
|
/**
|
|
5
|
-
* Creates a
|
|
5
|
+
* Creates a non-reactive async query API for lint reports.
|
|
6
|
+
* e.g. used in editor/.../Listheader.tsx
|
|
7
|
+
*
|
|
8
|
+
* TODO MESDK-50: reactivity should be restored in future
|
|
9
|
+
* See https://github.com/opral/monorepo/pull/2378 for why this design.
|
|
6
10
|
*/
|
|
7
11
|
export declare function createMessageLintReportsQuery(messagesQuery: MessageQueryApi, settings: () => ProjectSettings, installedMessageLintRules: () => Array<InstalledMessageLintRule>, resolvedModules: () => Awaited<ReturnType<typeof resolveModules>> | undefined): InlangProject["query"]["messageLintReports"];
|
|
8
12
|
//# sourceMappingURL=createMessageLintReportsQuery.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createMessageLintReportsQuery.d.ts","sourceRoot":"","sources":["../src/createMessageLintReportsQuery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,aAAa,EACb,wBAAwB,EAExB,eAAe,EAEf,MAAM,UAAU,CAAA;AACjB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;
|
|
1
|
+
{"version":3,"file":"createMessageLintReportsQuery.d.ts","sourceRoot":"","sources":["../src/createMessageLintReportsQuery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,aAAa,EACb,wBAAwB,EAExB,eAAe,EAEf,MAAM,UAAU,CAAA;AACjB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAWhE;;;;;;GAMG;AACH,wBAAgB,6BAA6B,CAC5C,aAAa,EAAE,eAAe,EAC9B,QAAQ,EAAE,MAAM,eAAe,EAC/B,yBAAyB,EAAE,MAAM,KAAK,CAAC,wBAAwB,CAAC,EAChE,eAAe,EAAE,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,GAAG,SAAS,GAC3E,aAAa,CAAC,OAAO,CAAC,CAAC,oBAAoB,CAAC,CA8E9C"}
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import { lintSingleMessage } from "./lint/index.js";
|
|
2
|
+
import _debug from "debug";
|
|
3
|
+
const debug = _debug("sdk:lintReports");
|
|
2
4
|
function sleep(ms) {
|
|
3
5
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
4
6
|
}
|
|
5
7
|
/**
|
|
6
|
-
* Creates a
|
|
8
|
+
* Creates a non-reactive async query API for lint reports.
|
|
9
|
+
* e.g. used in editor/.../Listheader.tsx
|
|
10
|
+
*
|
|
11
|
+
* TODO MESDK-50: reactivity should be restored in future
|
|
12
|
+
* See https://github.com/opral/monorepo/pull/2378 for why this design.
|
|
7
13
|
*/
|
|
8
14
|
export function createMessageLintReportsQuery(messagesQuery, settings, installedMessageLintRules, resolvedModules) {
|
|
9
15
|
const index = new Map();
|
|
@@ -28,7 +34,7 @@ export function createMessageLintReportsQuery(messagesQuery, settings, installed
|
|
|
28
34
|
message: message,
|
|
29
35
|
}).then((report) => {
|
|
30
36
|
if (report.errors.length === 0 && index.get(message.id) !== report.data) {
|
|
31
|
-
|
|
37
|
+
debug("lintSingleMessage", message.id, report.data.length);
|
|
32
38
|
index.set(message.id, report.data);
|
|
33
39
|
}
|
|
34
40
|
});
|
|
@@ -63,10 +69,13 @@ export function createMessageLintReportsQuery(messagesQuery, settings, installed
|
|
|
63
69
|
return {
|
|
64
70
|
getAll: async () => {
|
|
65
71
|
await sleep(0); // evaluate on next tick to allow for out-of-order effects
|
|
66
|
-
|
|
72
|
+
const flatValues = [...index.values()].flat();
|
|
73
|
+
debug("getAll", flatValues.length);
|
|
74
|
+
return structuredClone(flatValues.length === 0 ? [] : flatValues);
|
|
67
75
|
},
|
|
68
76
|
get: async (args) => {
|
|
69
77
|
await sleep(0); // evaluate on next tick to allow for out-of-order effects
|
|
78
|
+
debug("get", args.where.messageId);
|
|
70
79
|
return structuredClone(index.get(args.where.messageId) ?? []);
|
|
71
80
|
},
|
|
72
81
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createMessagesQuery.d.ts","sourceRoot":"","sources":["../src/createMessagesQuery.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAyC,MAAM,UAAU,CAAA;AAEpF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAA;AAEzE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAKnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AA4B/D,KAAK,6BAA6B,GAAG;IACpC,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,iBAAiB,CAAA;IAC5B,QAAQ,EAAE,MAAM,eAAe,GAAG,SAAS,CAAA;IAC3C,eAAe,EAAE,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,GAAG,SAAS,CAAA;IAC7E,0BAA0B,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,CAAA;IAC/C,mBAAmB,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,CAAA;IACxC,mBAAmB,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,CAAA;CACxC,CAAA;AACD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,EACnC,WAAW,EACX,SAAS,EACT,QAAQ,EACR,eAAe,EACf,0BAA0B,EAC1B,mBAAmB,EACnB,mBAAmB,GACnB,EAAE,6BAA6B,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC,
|
|
1
|
+
{"version":3,"file":"createMessagesQuery.d.ts","sourceRoot":"","sources":["../src/createMessagesQuery.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAyC,MAAM,UAAU,CAAA;AAEpF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAA;AAEzE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAKnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AA4B/D,KAAK,6BAA6B,GAAG;IACpC,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,iBAAiB,CAAA;IAC5B,QAAQ,EAAE,MAAM,eAAe,GAAG,SAAS,CAAA;IAC3C,eAAe,EAAE,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,GAAG,SAAS,CAAA;IAC7E,0BAA0B,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,CAAA;IAC/C,mBAAmB,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,CAAA;IACxC,mBAAmB,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,CAAA;CACxC,CAAA;AACD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,EACnC,WAAW,EACX,SAAS,EACT,QAAQ,EACR,eAAe,EACf,0BAA0B,EAC1B,mBAAmB,EACnB,mBAAmB,GACnB,EAAE,6BAA6B,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC,CA6MpE"}
|
|
@@ -9,7 +9,7 @@ import _debug from "debug";
|
|
|
9
9
|
import { releaseLock } from "./persistence/filelock/releaseLock.js";
|
|
10
10
|
import { PluginLoadMessagesError, PluginSaveMessagesError } from "./errors.js";
|
|
11
11
|
import { humanIdHash } from "./storage/human-id/human-readable-id.js";
|
|
12
|
-
const debug = _debug("sdk:
|
|
12
|
+
const debug = _debug("sdk:messages");
|
|
13
13
|
function sleep(ms) {
|
|
14
14
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
15
15
|
}
|
|
@@ -53,13 +53,6 @@ export function createMessagesQuery({ projectPath, nodeishFs, settings, resolved
|
|
|
53
53
|
const resolvedPluginApi = resolvedModules()?.resolvedPluginApi;
|
|
54
54
|
if (!resolvedPluginApi)
|
|
55
55
|
return;
|
|
56
|
-
const abortController = new AbortController();
|
|
57
|
-
// called between executions of effects as well as on disposal
|
|
58
|
-
onCleanup(() => {
|
|
59
|
-
// stop listening on fs events
|
|
60
|
-
abortController.abort();
|
|
61
|
-
delegate?.onCleanup();
|
|
62
|
-
});
|
|
63
56
|
const fsWithWatcher = createNodeishFsWithWatcher({
|
|
64
57
|
nodeishFs: nodeishFs,
|
|
65
58
|
// this message is called whenever a file changes that was read earlier by this filesystem
|
|
@@ -75,7 +68,12 @@ export function createMessagesQuery({ projectPath, nodeishFs, settings, resolved
|
|
|
75
68
|
onLoadMessageResult();
|
|
76
69
|
});
|
|
77
70
|
},
|
|
78
|
-
|
|
71
|
+
});
|
|
72
|
+
// called between executions of effects as well as on disposal
|
|
73
|
+
onCleanup(() => {
|
|
74
|
+
// stop listening on fs events
|
|
75
|
+
fsWithWatcher.stopWatching();
|
|
76
|
+
delegate?.onCleanup();
|
|
79
77
|
});
|
|
80
78
|
if (!resolvedPluginApi.loadMessages) {
|
|
81
79
|
onInitialMessageLoadResult(new Error("no loadMessages in resolved Modules found"));
|
|
@@ -3,11 +3,6 @@ import { ProjectSettings } from "@inlang/project-settings";
|
|
|
3
3
|
/**
|
|
4
4
|
* Creates a new project in the given directory.
|
|
5
5
|
* The directory must be an absolute path, must not exist, and must end with {name}.inlang
|
|
6
|
-
* Uses defaultProjectSettings unless projectSettings are provided.
|
|
7
|
-
*
|
|
8
|
-
* @param projectPath - Absolute path to the [name].inlang directory
|
|
9
|
-
* @param repo - An instance of a lix repo as returned by `openRepository`
|
|
10
|
-
* @param projectSettings - Optional project settings to use for the new project.
|
|
11
6
|
*/
|
|
12
7
|
export declare function createNewProject(args: {
|
|
13
8
|
projectPath: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createNewProject.d.ts","sourceRoot":"","sources":["../src/createNewProject.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAI1D
|
|
1
|
+
{"version":3,"file":"createNewProject.d.ts","sourceRoot":"","sources":["../src/createNewProject.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAI1D;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC5C,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,UAAU,CAAA;IAChB,eAAe,EAAE,eAAe,CAAA;CAChC,GAAG,OAAO,CAAC,IAAI,CAAC,CAYhB"}
|
package/dist/createNewProject.js
CHANGED
|
@@ -4,11 +4,6 @@ import { defaultProjectSettings } from "./defaultProjectSettings.js";
|
|
|
4
4
|
/**
|
|
5
5
|
* Creates a new project in the given directory.
|
|
6
6
|
* The directory must be an absolute path, must not exist, and must end with {name}.inlang
|
|
7
|
-
* Uses defaultProjectSettings unless projectSettings are provided.
|
|
8
|
-
*
|
|
9
|
-
* @param projectPath - Absolute path to the [name].inlang directory
|
|
10
|
-
* @param repo - An instance of a lix repo as returned by `openRepository`
|
|
11
|
-
* @param projectSettings - Optional project settings to use for the new project.
|
|
12
7
|
*/
|
|
13
8
|
export async function createNewProject(args) {
|
|
14
9
|
assertValidProjectPath(args.projectPath);
|
|
@@ -8,6 +8,7 @@ import type { NodeishFilesystem } from "@lix-js/fs";
|
|
|
8
8
|
export declare const createNodeishFsWithWatcher: (args: {
|
|
9
9
|
nodeishFs: NodeishFilesystem;
|
|
10
10
|
updateMessages: () => void;
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
}) => NodeishFilesystem & {
|
|
12
|
+
stopWatching: () => void;
|
|
13
|
+
};
|
|
13
14
|
//# sourceMappingURL=createNodeishFsWithWatcher.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createNodeishFsWithWatcher.d.ts","sourceRoot":"","sources":["../src/createNodeishFsWithWatcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAEnD;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,SAAU;IAChD,SAAS,EAAE,iBAAiB,CAAA;IAC5B,cAAc,EAAE,MAAM,IAAI,CAAA;
|
|
1
|
+
{"version":3,"file":"createNodeishFsWithWatcher.d.ts","sourceRoot":"","sources":["../src/createNodeishFsWithWatcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAEnD;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,SAAU;IAChD,SAAS,EAAE,iBAAiB,CAAA;IAC5B,cAAc,EAAE,MAAM,IAAI,CAAA;CAC1B;kBACc,MAAM,IAAI;CA6DxB,CAAA"}
|
|
@@ -6,12 +6,22 @@
|
|
|
6
6
|
*/
|
|
7
7
|
export const createNodeishFsWithWatcher = (args) => {
|
|
8
8
|
const pathList = [];
|
|
9
|
+
let abortControllers = [];
|
|
10
|
+
const stopWatching = () => {
|
|
11
|
+
for (const ac of abortControllers) {
|
|
12
|
+
ac.abort();
|
|
13
|
+
}
|
|
14
|
+
// release references
|
|
15
|
+
abortControllers = [];
|
|
16
|
+
};
|
|
9
17
|
const makeWatcher = (path) => {
|
|
10
18
|
;
|
|
11
19
|
(async () => {
|
|
12
20
|
try {
|
|
21
|
+
const ac = new AbortController();
|
|
22
|
+
abortControllers.push(ac);
|
|
13
23
|
const watcher = args.nodeishFs.watch(path, {
|
|
14
|
-
signal:
|
|
24
|
+
signal: ac.signal,
|
|
15
25
|
persistent: false,
|
|
16
26
|
});
|
|
17
27
|
if (watcher) {
|
|
@@ -51,5 +61,6 @@ export const createNodeishFsWithWatcher = (args) => {
|
|
|
51
61
|
writeFile: args.nodeishFs.writeFile,
|
|
52
62
|
watch: args.nodeishFs.watch,
|
|
53
63
|
stat: args.nodeishFs.stat,
|
|
64
|
+
stopWatching,
|
|
54
65
|
};
|
|
55
66
|
};
|
|
@@ -4,13 +4,11 @@ import { createNodeishFsWithWatcher } from "./createNodeishFsWithWatcher.js";
|
|
|
4
4
|
describe("watcher", () => {
|
|
5
5
|
it("should trigger the update function when file changes", async () => {
|
|
6
6
|
let counter = 0;
|
|
7
|
-
const abortController = new AbortController();
|
|
8
7
|
const fs = createNodeishFsWithWatcher({
|
|
9
8
|
nodeishFs: createNodeishMemoryFs(),
|
|
10
9
|
updateMessages: () => {
|
|
11
10
|
counter++;
|
|
12
11
|
},
|
|
13
|
-
abortController,
|
|
14
12
|
});
|
|
15
13
|
// establish watcher
|
|
16
14
|
await fs.writeFile("file.txt", "a");
|
|
@@ -30,7 +28,7 @@ describe("watcher", () => {
|
|
|
30
28
|
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
31
29
|
//check if update function was called
|
|
32
30
|
expect(counter).toBe(2);
|
|
33
|
-
|
|
31
|
+
fs.stopWatching();
|
|
34
32
|
// change file
|
|
35
33
|
await fs.writeFile("file.txt", "b");
|
|
36
34
|
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"acquireFileLock.d.ts","sourceRoot":"","sources":["../../../src/persistence/filelock/acquireFileLock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAQnD,wBAAsB,eAAe,CACpC,EAAE,EAAE,iBAAiB,EACrB,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,QAAQ,GAAE,MAAU,GAClB,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"acquireFileLock.d.ts","sourceRoot":"","sources":["../../../src/persistence/filelock/acquireFileLock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAQnD,wBAAsB,eAAe,CACpC,EAAE,EAAE,iBAAiB,EACrB,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,QAAQ,GAAE,MAAU,GAClB,OAAO,CAAC,MAAM,CAAC,CAgHjB"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {} from "@lix-js/fs";
|
|
2
2
|
import _debug from "debug";
|
|
3
|
-
const debug = _debug("sdk:
|
|
3
|
+
const debug = _debug("sdk:fileLock");
|
|
4
4
|
const maxRetries = 10;
|
|
5
5
|
const nProbes = 50;
|
|
6
6
|
const probeInterval = 100;
|
|
7
7
|
export async function acquireFileLock(fs, lockDirPath, lockOrigin, tryCount = 0) {
|
|
8
8
|
if (tryCount > maxRetries) {
|
|
9
|
-
throw new Error(lockOrigin
|
|
9
|
+
throw new Error(`${lockOrigin} exceeded maximum retries (${maxRetries}) to acquire lockfile ${tryCount}`);
|
|
10
10
|
}
|
|
11
11
|
try {
|
|
12
12
|
debug(lockOrigin + " tries to acquire a lockfile Retry Nr.: " + tryCount);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {} from "@lix-js/fs";
|
|
2
2
|
import _debug from "debug";
|
|
3
|
-
const debug = _debug("sdk:
|
|
3
|
+
const debug = _debug("sdk:fileLock");
|
|
4
4
|
export async function releaseLock(fs, lockDirPath, lockOrigin, lockTime) {
|
|
5
5
|
debug(lockOrigin + " releasing the lock ");
|
|
6
6
|
try {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inlang/sdk",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.34.
|
|
4
|
+
"version": "0.34.9",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public"
|
|
@@ -37,10 +37,10 @@
|
|
|
37
37
|
"@inlang/language-tag": "1.5.1",
|
|
38
38
|
"@inlang/message": "2.1.0",
|
|
39
39
|
"@inlang/message-lint-rule": "1.4.7",
|
|
40
|
+
"@inlang/module": "1.2.11",
|
|
40
41
|
"@inlang/plugin": "2.4.11",
|
|
41
42
|
"@inlang/project-settings": "2.4.2",
|
|
42
43
|
"@inlang/result": "1.1.0",
|
|
43
|
-
"@inlang/module": "1.2.11",
|
|
44
44
|
"@inlang/translatable": "1.3.1",
|
|
45
45
|
"@lix-js/client": "1.4.0",
|
|
46
46
|
"@lix-js/fs": "1.0.0"
|
package/src/api.ts
CHANGED
|
@@ -65,7 +65,7 @@ export type InlangProject = {
|
|
|
65
65
|
|
|
66
66
|
/**
|
|
67
67
|
* WIP template for async V2 crud interfaces
|
|
68
|
-
* E.g. `project.messageBundles.get({ id: "..." })`
|
|
68
|
+
* E.g. `await project.messageBundles.get({ id: "..." })`
|
|
69
69
|
**/
|
|
70
70
|
interface Query<T> {
|
|
71
71
|
get: (args: unknown) => Promise<T>
|
|
@@ -10,12 +10,19 @@ import type { resolveModules } from "./resolve-modules/index.js"
|
|
|
10
10
|
import type { MessageLintReport, Message } from "./versionedInterfaces.js"
|
|
11
11
|
import { lintSingleMessage } from "./lint/index.js"
|
|
12
12
|
|
|
13
|
+
import _debug from "debug"
|
|
14
|
+
const debug = _debug("sdk:lintReports")
|
|
15
|
+
|
|
13
16
|
function sleep(ms: number) {
|
|
14
17
|
return new Promise((resolve) => setTimeout(resolve, ms))
|
|
15
18
|
}
|
|
16
19
|
|
|
17
20
|
/**
|
|
18
|
-
* Creates a
|
|
21
|
+
* Creates a non-reactive async query API for lint reports.
|
|
22
|
+
* e.g. used in editor/.../Listheader.tsx
|
|
23
|
+
*
|
|
24
|
+
* TODO MESDK-50: reactivity should be restored in future
|
|
25
|
+
* See https://github.com/opral/monorepo/pull/2378 for why this design.
|
|
19
26
|
*/
|
|
20
27
|
export function createMessageLintReportsQuery(
|
|
21
28
|
messagesQuery: MessageQueryApi,
|
|
@@ -51,7 +58,7 @@ export function createMessageLintReportsQuery(
|
|
|
51
58
|
message: message,
|
|
52
59
|
}).then((report) => {
|
|
53
60
|
if (report.errors.length === 0 && index.get(message.id) !== report.data) {
|
|
54
|
-
|
|
61
|
+
debug("lintSingleMessage", message.id, report.data.length)
|
|
55
62
|
index.set(message.id, report.data)
|
|
56
63
|
}
|
|
57
64
|
})
|
|
@@ -90,12 +97,13 @@ export function createMessageLintReportsQuery(
|
|
|
90
97
|
return {
|
|
91
98
|
getAll: async () => {
|
|
92
99
|
await sleep(0) // evaluate on next tick to allow for out-of-order effects
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
)
|
|
100
|
+
const flatValues = [...index.values()].flat()
|
|
101
|
+
debug("getAll", flatValues.length)
|
|
102
|
+
return structuredClone(flatValues.length === 0 ? [] : flatValues)
|
|
96
103
|
},
|
|
97
104
|
get: async (args: Parameters<MessageLintReportsQueryApi["get"]>[0]) => {
|
|
98
105
|
await sleep(0) // evaluate on next tick to allow for out-of-order effects
|
|
106
|
+
debug("get", args.where.messageId)
|
|
99
107
|
return structuredClone(index.get(args.where.messageId) ?? [])
|
|
100
108
|
},
|
|
101
109
|
}
|
|
@@ -15,7 +15,7 @@ import type { ProjectSettings } from "@inlang/project-settings"
|
|
|
15
15
|
import { releaseLock } from "./persistence/filelock/releaseLock.js"
|
|
16
16
|
import { PluginLoadMessagesError, PluginSaveMessagesError } from "./errors.js"
|
|
17
17
|
import { humanIdHash } from "./storage/human-id/human-readable-id.js"
|
|
18
|
-
const debug = _debug("sdk:
|
|
18
|
+
const debug = _debug("sdk:messages")
|
|
19
19
|
|
|
20
20
|
function sleep(ms: number) {
|
|
21
21
|
return new Promise((resolve) => setTimeout(resolve, ms))
|
|
@@ -103,14 +103,6 @@ export function createMessagesQuery({
|
|
|
103
103
|
const resolvedPluginApi = resolvedModules()?.resolvedPluginApi
|
|
104
104
|
if (!resolvedPluginApi) return
|
|
105
105
|
|
|
106
|
-
const abortController = new AbortController()
|
|
107
|
-
// called between executions of effects as well as on disposal
|
|
108
|
-
onCleanup(() => {
|
|
109
|
-
// stop listening on fs events
|
|
110
|
-
abortController.abort()
|
|
111
|
-
delegate?.onCleanup()
|
|
112
|
-
})
|
|
113
|
-
|
|
114
106
|
const fsWithWatcher = createNodeishFsWithWatcher({
|
|
115
107
|
nodeishFs: nodeishFs,
|
|
116
108
|
// this message is called whenever a file changes that was read earlier by this filesystem
|
|
@@ -133,7 +125,13 @@ export function createMessagesQuery({
|
|
|
133
125
|
onLoadMessageResult()
|
|
134
126
|
})
|
|
135
127
|
},
|
|
136
|
-
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
// called between executions of effects as well as on disposal
|
|
131
|
+
onCleanup(() => {
|
|
132
|
+
// stop listening on fs events
|
|
133
|
+
fsWithWatcher.stopWatching()
|
|
134
|
+
delegate?.onCleanup()
|
|
137
135
|
})
|
|
138
136
|
|
|
139
137
|
if (!resolvedPluginApi.loadMessages) {
|
package/src/createNewProject.ts
CHANGED
|
@@ -6,11 +6,6 @@ import { defaultProjectSettings } from "./defaultProjectSettings.js"
|
|
|
6
6
|
/**
|
|
7
7
|
* Creates a new project in the given directory.
|
|
8
8
|
* The directory must be an absolute path, must not exist, and must end with {name}.inlang
|
|
9
|
-
* Uses defaultProjectSettings unless projectSettings are provided.
|
|
10
|
-
*
|
|
11
|
-
* @param projectPath - Absolute path to the [name].inlang directory
|
|
12
|
-
* @param repo - An instance of a lix repo as returned by `openRepository`
|
|
13
|
-
* @param projectSettings - Optional project settings to use for the new project.
|
|
14
9
|
*/
|
|
15
10
|
export async function createNewProject(args: {
|
|
16
11
|
projectPath: string
|
|
@@ -6,14 +6,11 @@ describe("watcher", () => {
|
|
|
6
6
|
it("should trigger the update function when file changes", async () => {
|
|
7
7
|
let counter = 0
|
|
8
8
|
|
|
9
|
-
const abortController = new AbortController()
|
|
10
|
-
|
|
11
9
|
const fs = createNodeishFsWithWatcher({
|
|
12
10
|
nodeishFs: createNodeishMemoryFs(),
|
|
13
11
|
updateMessages: () => {
|
|
14
12
|
counter++
|
|
15
13
|
},
|
|
16
|
-
abortController,
|
|
17
14
|
})
|
|
18
15
|
|
|
19
16
|
// establish watcher
|
|
@@ -41,7 +38,7 @@ describe("watcher", () => {
|
|
|
41
38
|
//check if update function was called
|
|
42
39
|
expect(counter).toBe(2)
|
|
43
40
|
|
|
44
|
-
|
|
41
|
+
fs.stopWatching()
|
|
45
42
|
|
|
46
43
|
// change file
|
|
47
44
|
await fs.writeFile("file.txt", "b")
|
|
@@ -9,15 +9,27 @@ import type { NodeishFilesystem } from "@lix-js/fs"
|
|
|
9
9
|
export const createNodeishFsWithWatcher = (args: {
|
|
10
10
|
nodeishFs: NodeishFilesystem
|
|
11
11
|
updateMessages: () => void
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
}): NodeishFilesystem & {
|
|
13
|
+
stopWatching: () => void
|
|
14
|
+
} => {
|
|
14
15
|
const pathList: string[] = []
|
|
16
|
+
let abortControllers: AbortController[] = []
|
|
17
|
+
|
|
18
|
+
const stopWatching = () => {
|
|
19
|
+
for (const ac of abortControllers) {
|
|
20
|
+
ac.abort()
|
|
21
|
+
}
|
|
22
|
+
// release references
|
|
23
|
+
abortControllers = [];
|
|
24
|
+
}
|
|
15
25
|
|
|
16
26
|
const makeWatcher = (path: string) => {
|
|
17
27
|
;(async () => {
|
|
18
28
|
try {
|
|
29
|
+
const ac = new AbortController()
|
|
30
|
+
abortControllers.push(ac)
|
|
19
31
|
const watcher = args.nodeishFs.watch(path, {
|
|
20
|
-
signal:
|
|
32
|
+
signal: ac.signal,
|
|
21
33
|
persistent: false,
|
|
22
34
|
})
|
|
23
35
|
if (watcher) {
|
|
@@ -57,5 +69,6 @@ export const createNodeishFsWithWatcher = (args: {
|
|
|
57
69
|
writeFile: args.nodeishFs.writeFile,
|
|
58
70
|
watch: args.nodeishFs.watch,
|
|
59
71
|
stat: args.nodeishFs.stat,
|
|
72
|
+
stopWatching,
|
|
60
73
|
}
|
|
61
74
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type NodeishFilesystem } from "@lix-js/fs"
|
|
2
2
|
import type { NodeishStats } from "@lix-js/fs"
|
|
3
3
|
import _debug from "debug"
|
|
4
|
-
const debug = _debug("sdk:
|
|
4
|
+
const debug = _debug("sdk:fileLock")
|
|
5
5
|
|
|
6
6
|
const maxRetries = 10
|
|
7
7
|
const nProbes = 50
|
|
@@ -13,7 +13,9 @@ export async function acquireFileLock(
|
|
|
13
13
|
tryCount: number = 0
|
|
14
14
|
): Promise<number> {
|
|
15
15
|
if (tryCount > maxRetries) {
|
|
16
|
-
throw new Error(
|
|
16
|
+
throw new Error(
|
|
17
|
+
`${lockOrigin} exceeded maximum retries (${maxRetries}) to acquire lockfile ${tryCount}`
|
|
18
|
+
)
|
|
17
19
|
}
|
|
18
20
|
|
|
19
21
|
try {
|