@inlang/sdk 0.34.8 → 0.34.10

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.
Files changed (55) hide show
  1. package/dist/adapter/solidAdapter.js +1 -1
  2. package/dist/adapter/solidAdapter.test.js +60 -23
  3. package/dist/api.d.ts +16 -8
  4. package/dist/api.d.ts.map +1 -1
  5. package/dist/createMessageLintReportsQuery.d.ts +5 -1
  6. package/dist/createMessageLintReportsQuery.d.ts.map +1 -1
  7. package/dist/createMessageLintReportsQuery.js +165 -62
  8. package/dist/createMessagesQuery.d.ts.map +1 -1
  9. package/dist/createMessagesQuery.js +30 -12
  10. package/dist/createNewProject.d.ts +0 -5
  11. package/dist/createNewProject.d.ts.map +1 -1
  12. package/dist/createNewProject.js +0 -5
  13. package/dist/lint/message/lintSingleMessage.d.ts.map +1 -1
  14. package/dist/lint/message/lintSingleMessage.js +3 -1
  15. package/dist/loadProject.d.ts.map +1 -1
  16. package/dist/loadProject.js +6 -2
  17. package/dist/loadProject.test.js +38 -25
  18. package/dist/persistence/filelock/acquireFileLock.d.ts.map +1 -1
  19. package/dist/persistence/filelock/acquireFileLock.js +2 -2
  20. package/dist/persistence/filelock/releaseLock.js +1 -1
  21. package/dist/reactivity/solid.d.ts +2 -1
  22. package/dist/reactivity/solid.d.ts.map +1 -1
  23. package/dist/reactivity/solid.js +3 -2
  24. package/dist/reactivity/solid.test.js +38 -1
  25. package/dist/v2/createMessageBundle.d.ts +25 -0
  26. package/dist/v2/createMessageBundle.d.ts.map +1 -0
  27. package/dist/v2/createMessageBundle.js +36 -0
  28. package/dist/v2/createMessageBundle.test.d.ts +2 -0
  29. package/dist/v2/createMessageBundle.test.d.ts.map +1 -0
  30. package/dist/v2/createMessageBundle.test.js +92 -0
  31. package/dist/v2/mocks/plural/bundle.d.ts +3 -0
  32. package/dist/v2/mocks/plural/bundle.d.ts.map +1 -0
  33. package/dist/v2/mocks/plural/bundle.js +140 -0
  34. package/dist/v2/mocks/plural/bundle.test.d.ts +2 -0
  35. package/dist/v2/mocks/plural/bundle.test.d.ts.map +1 -0
  36. package/dist/v2/mocks/plural/bundle.test.js +15 -0
  37. package/package.json +3 -3
  38. package/src/adapter/solidAdapter.test.ts +78 -33
  39. package/src/adapter/solidAdapter.ts +1 -1
  40. package/src/api.ts +15 -8
  41. package/src/createMessageLintReportsQuery.ts +190 -67
  42. package/src/createMessagesQuery.ts +33 -12
  43. package/src/createNewProject.ts +0 -5
  44. package/src/createNodeishFsWithWatcher.ts +1 -1
  45. package/src/lint/message/lintSingleMessage.ts +4 -1
  46. package/src/loadProject.test.ts +45 -24
  47. package/src/loadProject.ts +7 -2
  48. package/src/persistence/filelock/acquireFileLock.ts +4 -2
  49. package/src/persistence/filelock/releaseLock.ts +1 -1
  50. package/src/reactivity/solid.test.ts +54 -1
  51. package/src/reactivity/solid.ts +3 -0
  52. package/src/v2/createMessageBundle.test.ts +95 -0
  53. package/src/v2/createMessageBundle.ts +43 -0
  54. package/src/v2/mocks/plural/bundle.test.ts +18 -0
  55. package/src/v2/mocks/plural/bundle.ts +142 -0
@@ -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;;;;;;;;GAQG;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"}
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"}
@@ -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);
@@ -1 +1 @@
1
- {"version":3,"file":"lintSingleMessage.d.ts","sourceRoot":"","sources":["../../../src/lint/message/lintSingleMessage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAA;AACnF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,EAAE,4BAA4B,EAAE,MAAM,aAAa,CAAA;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAE/D;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,SAAgB;IAC7C,QAAQ,EAAE,eAAe,GAAG,SAAS,KAAK,eAAe,EAAE,uBAAuB,CAAC,CAAC,CAAA;IACpF,KAAK,EAAE,eAAe,EAAE,CAAA;IACxB,QAAQ,EAAE,OAAO,EAAE,CAAA;IACnB,OAAO,EAAE,OAAO,CAAA;CAChB;UAAmB,iBAAiB,EAAE;YAAU,4BAA4B,EAAE;EAsC9E,CAAA"}
1
+ {"version":3,"file":"lintSingleMessage.d.ts","sourceRoot":"","sources":["../../../src/lint/message/lintSingleMessage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAA;AACnF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,EAAE,4BAA4B,EAAE,MAAM,aAAa,CAAA;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAE/D;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,SAAgB;IAC7C,QAAQ,EAAE,eAAe,GAAG,SAAS,KAAK,eAAe,EAAE,uBAAuB,CAAC,CAAC,CAAA;IACpF,KAAK,EAAE,eAAe,EAAE,CAAA;IACxB,QAAQ,EAAE,OAAO,EAAE,CAAA;IACnB,OAAO,EAAE,OAAO,CAAA;CAChB;UAAmB,iBAAiB,EAAE;YAAU,4BAA4B,EAAE;EAyC9E,CAAA"}
@@ -32,5 +32,7 @@ export const lintSingleMessage = async (args) => {
32
32
  }
33
33
  });
34
34
  await Promise.all(promises);
35
- return { data: reports, errors };
35
+ // we sort the reports by rule id to allow us to easyly compare both
36
+ const sortedReports = reports.sort((r1, r2) => r1.ruleId.localeCompare(r2.ruleId));
37
+ return { data: sortedReports, errors };
36
38
  };
@@ -1 +1 @@
1
- {"version":3,"file":"loadProject.d.ts","sourceRoot":"","sources":["../src/loadProject.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACX,aAAa,EAGb,YAAY,EACZ,MAAM,UAAU,CAAA;AACjB,OAAO,EAAE,KAAK,cAAc,EAAkB,MAAM,4BAA4B,CAAA;AAkBhF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAYhD;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE;IACvC,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,UAAU,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,cAAc,CAAA;CACxB,GAAG,OAAO,CAAC,aAAa,CAAC,CAiOzB;AA+GD,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,CAQtE"}
1
+ {"version":3,"file":"loadProject.d.ts","sourceRoot":"","sources":["../src/loadProject.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACX,aAAa,EAGb,YAAY,EACZ,MAAM,UAAU,CAAA;AACjB,OAAO,EAAE,KAAK,cAAc,EAAkB,MAAM,4BAA4B,CAAA;AAkBhF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAYhD;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE;IACvC,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,UAAU,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,cAAc,CAAA;CACxB,GAAG,OAAO,CAAC,aAAa,CAAC,CAsOzB;AA+GD,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,CAQtE"}
@@ -1,7 +1,7 @@
1
1
  import { resolveModules } from "./resolve-modules/index.js";
2
2
  import { TypeCompiler, ValueErrorType } from "@sinclair/typebox/compiler";
3
3
  import { ProjectSettingsFileJSONSyntaxError, ProjectSettingsFileNotFoundError, ProjectSettingsInvalidError, } from "./errors.js";
4
- import { createRoot, createSignal, createEffect } from "./reactivity/solid.js";
4
+ import { createRoot, createSignal, createEffect, batch } from "./reactivity/solid.js";
5
5
  import { createMessagesQuery } from "./createMessagesQuery.js";
6
6
  import { createMessageLintReportsQuery } from "./createMessageLintReportsQuery.js";
7
7
  import { ProjectSettings } from "./versionedInterfaces.js";
@@ -72,7 +72,11 @@ export async function loadProject(args) {
72
72
  pathPattern: projectPath + "/messages.json",
73
73
  };
74
74
  }
75
- _setSettings(validatedSettings);
75
+ batch(() => {
76
+ // reset the resolved modules first - since they are no longer valid at that point
77
+ setResolvedModules(undefined);
78
+ _setSettings(validatedSettings);
79
+ });
76
80
  writeSettingsToDisk(validatedSettings);
77
81
  return { data: undefined };
78
82
  }
@@ -515,8 +515,8 @@ describe("functionality", () => {
515
515
  _import,
516
516
  });
517
517
  await new Promise((resolve) => setTimeout(resolve, 510));
518
- expect(await project.query.messageLintReports.getAll()).toHaveLength(1);
519
- expect((await project.query.messageLintReports.getAll())?.[0]?.ruleId).toBe(_mockLintRule.id);
518
+ expect(await project.query.messageLintReports.getAll.settled()).toHaveLength(1);
519
+ expect((await project.query.messageLintReports.getAll.settled())?.[0]?.ruleId).toBe(_mockLintRule.id);
520
520
  expect(project.installed.messageLintRules()).toHaveLength(1);
521
521
  });
522
522
  it("should return lint reports for a single message", async () => {
@@ -840,26 +840,6 @@ describe("functionality", () => {
840
840
  });
841
841
  });
842
842
  describe("lint", () => {
843
- it.todo("should throw if lint reports are not initialized yet", async () => {
844
- const repo = await mockRepo();
845
- const fs = repo.nodeishFs;
846
- await fs.mkdir("/user/project", { recursive: true });
847
- await fs.writeFile("/user/project/project.inlang.json", JSON.stringify(settings));
848
- const project = await loadProject({
849
- projectPath: "/user/project/project.inlang.json",
850
- repo,
851
- _import,
852
- });
853
- // TODO: test with real lint rules
854
- try {
855
- const r = await project.query.messageLintReports.getAll();
856
- expect(r).toEqual(undefined);
857
- throw new Error("Should not reach this");
858
- }
859
- catch (e) {
860
- expect(e.message).toBe("lint not initialized yet");
861
- }
862
- });
863
843
  it("should return the message lint reports", async () => {
864
844
  const settings = {
865
845
  sourceLanguageTag: "en",
@@ -878,7 +858,7 @@ describe("functionality", () => {
878
858
  }),
879
859
  });
880
860
  // TODO: test with real lint rules
881
- const r = await project.query.messageLintReports.getAll();
861
+ const r = await project.query.messageLintReports.getAll.settled();
882
862
  expect(r).toEqual([]);
883
863
  });
884
864
  });
@@ -907,6 +887,22 @@ describe("functionality", () => {
907
887
  },
908
888
  ],
909
889
  };
890
+ const newMessage = {
891
+ id: "test2",
892
+ selectors: [],
893
+ variants: [
894
+ {
895
+ match: [],
896
+ languageTag: "en",
897
+ pattern: [
898
+ {
899
+ type: "Text",
900
+ value: "test",
901
+ },
902
+ ],
903
+ },
904
+ ],
905
+ };
910
906
  await fs.writeFile("./messages.json", JSON.stringify(messages));
911
907
  const getMessages = async (customFs) => {
912
908
  const file = await customFs.readFile("./messages.json", { encoding: "utf-8" });
@@ -938,8 +934,10 @@ describe("functionality", () => {
938
934
  }),
939
935
  });
940
936
  let counter = 0;
941
- project.query.messages.getAll.subscribe(() => {
937
+ let messageCount = 0;
938
+ project.query.messages.getAll.subscribe((messages) => {
942
939
  counter = counter + 1;
940
+ messageCount = messages.length;
943
941
  });
944
942
  // subscribe fires once
945
943
  expect(counter).toBe(1);
@@ -948,16 +946,31 @@ describe("functionality", () => {
948
946
  await new Promise((resolve) => setTimeout(resolve, 200)); // file event will lock a file and be handled sequentially - give it time to pickup the change
949
947
  // we didn't change the message we write into message.json - shouldn't change the messages
950
948
  expect(counter).toBe(1);
949
+ expect(messageCount).toBe(1);
951
950
  // saving the file without changing should trigger a change
952
951
  messages.data[0].variants[0].pattern[0].value = "changed";
953
952
  await fs.writeFile("./messages.json", JSON.stringify(messages));
954
953
  await new Promise((resolve) => setTimeout(resolve, 200)); // file event will lock a file and be handled sequentially - give it time to pickup the change
955
954
  expect(counter).toBe(2);
955
+ expect(messageCount).toBe(1);
956
956
  messages.data[0].variants[0].pattern[0].value = "changed3";
957
- // change file
957
+ // change file - update message
958
958
  await fs.writeFile("./messages.json", JSON.stringify(messages));
959
959
  await new Promise((resolve) => setTimeout(resolve, 200)); // file event will lock a file and be handled sequentially - give it time to pickup the change
960
960
  expect(counter).toBe(3);
961
+ expect(messageCount).toBe(1);
962
+ // change file - add a message
963
+ messages.data.push(newMessage);
964
+ await fs.writeFile("./messages.json", JSON.stringify(messages));
965
+ await new Promise((resolve) => setTimeout(resolve, 200)); // file event will lock a file and be handled sequentially - give it time to pickup the change
966
+ expect(counter).toBe(4);
967
+ expect(messageCount).toBe(2);
968
+ // change file - remove a message
969
+ messages.data.pop();
970
+ await fs.writeFile("./messages.json", JSON.stringify(messages));
971
+ await new Promise((resolve) => setTimeout(resolve, 200)); // file event will lock a file and be handled sequentially - give it time to pickup the change
972
+ expect(counter).toBe(5);
973
+ expect(messageCount).toBe(1);
961
974
  });
962
975
  });
963
976
  });
@@ -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,CA8GjB"}
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:acquireFileLock");
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 + " exceeded maximum Retries (5) to acquire lockfile " + tryCount);
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:releaseLock");
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 {
@@ -9,5 +9,6 @@ declare const from: typeof import("solid-js").from;
9
9
  declare const batch: typeof import("solid-js").batch;
10
10
  declare const getListener: typeof import("solid-js").getListener;
11
11
  declare const onCleanup: typeof import("solid-js").onCleanup;
12
- export { createSignal, createMemo, createRoot, createEffect, createResource, observable, from, batch, getListener, onCleanup, DEV, };
12
+ declare const untrack: typeof import("solid-js").untrack;
13
+ export { createSignal, createMemo, createRoot, createEffect, createResource, observable, from, batch, getListener, onCleanup, untrack, DEV, };
13
14
  //# sourceMappingURL=solid.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"solid.d.ts","sourceRoot":"","sources":["../../src/reactivity/solid.ts"],"names":[],"mappings":"AAAA,OAAO,EAWN,GAAG,EAEH,MAAM,wBAAwB,CAAA;AAE/B,QAAA,MAAM,YAAY,wCAA6D,CAAA;AAC/E,QAAA,MAAM,UAAU,sCAAyD,CAAA;AACzE,QAAA,MAAM,UAAU,sCAAyD,CAAA;AACzE,QAAA,MAAM,YAAY,wCAA6D,CAAA;AAC/E,QAAA,MAAM,cAAc,0CAAiE,CAAA;AACrF,QAAA,MAAM,UAAU,sCAAyD,CAAA;AACzE,QAAA,MAAM,IAAI,gCAA6C,CAAA;AACvD,QAAA,MAAM,KAAK,iCAA+C,CAAA;AAC1D,QAAA,MAAM,WAAW,uCAA2D,CAAA;AAC5E,QAAA,MAAM,SAAS,qCAAuD,CAAA;AAEtE,OAAO,EACN,YAAY,EACZ,UAAU,EACV,UAAU,EACV,YAAY,EACZ,cAAc,EACd,UAAU,EACV,IAAI,EACJ,KAAK,EACL,WAAW,EACX,SAAS,EACT,GAAG,GACH,CAAA"}
1
+ {"version":3,"file":"solid.d.ts","sourceRoot":"","sources":["../../src/reactivity/solid.ts"],"names":[],"mappings":"AAAA,OAAO,EAYN,GAAG,EAEH,MAAM,wBAAwB,CAAA;AAE/B,QAAA,MAAM,YAAY,wCAA6D,CAAA;AAC/E,QAAA,MAAM,UAAU,sCAAyD,CAAA;AACzE,QAAA,MAAM,UAAU,sCAAyD,CAAA;AACzE,QAAA,MAAM,YAAY,wCAA6D,CAAA;AAC/E,QAAA,MAAM,cAAc,0CAAiE,CAAA;AACrF,QAAA,MAAM,UAAU,sCAAyD,CAAA;AACzE,QAAA,MAAM,IAAI,gCAA6C,CAAA;AACvD,QAAA,MAAM,KAAK,iCAA+C,CAAA;AAC1D,QAAA,MAAM,WAAW,uCAA2D,CAAA;AAC5E,QAAA,MAAM,SAAS,qCAAuD,CAAA;AACtE,QAAA,MAAM,OAAO,mCAAmD,CAAA;AAEhE,OAAO,EACN,YAAY,EACZ,UAAU,EACV,UAAU,EACV,YAAY,EACZ,cAAc,EACd,UAAU,EACV,IAAI,EACJ,KAAK,EACL,WAAW,EACX,SAAS,EACT,OAAO,EACP,GAAG,GACH,CAAA"}
@@ -1,4 +1,4 @@
1
- import { createSignal as _createSignal, createMemo as _createMemo, createRoot as _createRoot, createEffect as _createEffect, createResource as _createResource, observable as _observable, batch as _batch, from as _from, getListener as _getListener, onCleanup as _onCleanup, DEV,
1
+ import { createSignal as _createSignal, createMemo as _createMemo, createRoot as _createRoot, createEffect as _createEffect, createResource as _createResource, untrack as _untrack, observable as _observable, batch as _batch, from as _from, getListener as _getListener, onCleanup as _onCleanup, DEV,
2
2
  // @ts-ignore
3
3
  } from "solid-js/dist/solid.js";
4
4
  const createSignal = _createSignal;
@@ -11,4 +11,5 @@ const from = _from;
11
11
  const batch = _batch;
12
12
  const getListener = _getListener;
13
13
  const onCleanup = _onCleanup;
14
- export { createSignal, createMemo, createRoot, createEffect, createResource, observable, from, batch, getListener, onCleanup, DEV, };
14
+ const untrack = _untrack;
15
+ export { createSignal, createMemo, createRoot, createEffect, createResource, observable, from, batch, getListener, onCleanup, untrack, DEV, };
@@ -1,5 +1,6 @@
1
1
  import { describe, it, expect } from "vitest";
2
- import { createRoot, createSignal, createEffect, createMemo, createResource } from "./solid.js";
2
+ import { createRoot, createSignal, createEffect, createMemo, createResource, untrack, } from "./solid.js";
3
+ import { ReactiveMap } from "./map.js";
3
4
  function sleep(ms) {
4
5
  return new Promise((resolve) => setTimeout(resolve, ms));
5
6
  }
@@ -155,3 +156,39 @@ describe("solid", () => {
155
156
  expect(memo()).toBe("memo = 2000");
156
157
  });
157
158
  });
159
+ describe("solid", () => {
160
+ it("solid reactive map allows to use untrack", () => {
161
+ // @ts-expect-error -- ReactiveMap seem to have problems type arguments here
162
+ const reactiveMap = new ReactiveMap();
163
+ const [plainSignal, setPlainSignal] = createSignal(0);
164
+ let shouldTriggerOnBoth = -1;
165
+ createEffect(() => {
166
+ shouldTriggerOnBoth++;
167
+ reactiveMap.values();
168
+ plainSignal();
169
+ });
170
+ let shouldTriggerOnReactiveMapOnly = -1;
171
+ createEffect(() => {
172
+ shouldTriggerOnReactiveMapOnly++;
173
+ reactiveMap.values();
174
+ untrack(() => plainSignal());
175
+ });
176
+ let shouldTriggerOnPlainSignalOnly = -1;
177
+ createEffect(() => {
178
+ shouldTriggerOnPlainSignalOnly++;
179
+ untrack(() => reactiveMap.values());
180
+ plainSignal();
181
+ });
182
+ expect(shouldTriggerOnBoth).toBe(0);
183
+ expect(shouldTriggerOnReactiveMapOnly).toBe(0);
184
+ expect(shouldTriggerOnPlainSignalOnly).toBe(0);
185
+ setPlainSignal(1);
186
+ expect(shouldTriggerOnBoth).toBe(1);
187
+ expect(shouldTriggerOnReactiveMapOnly).toBe(0);
188
+ expect(shouldTriggerOnPlainSignalOnly).toBe(1);
189
+ reactiveMap.set("a", "a");
190
+ expect(shouldTriggerOnBoth).toBe(2);
191
+ expect(shouldTriggerOnReactiveMapOnly).toBe(1);
192
+ expect(shouldTriggerOnPlainSignalOnly).toBe(1);
193
+ });
194
+ });
@@ -0,0 +1,25 @@
1
+ import { LanguageTag, MessageBundle, Message } from "./types.js";
2
+ /**
3
+ * create v2 MessageBundle
4
+ * @example createMessageBundle({
5
+ * id: "greeting",
6
+ * messages: [
7
+ * createMessage({locale: "en", text: "Hello world!"})
8
+ * createMessage({locale: "de", text: "Hallo Welt!"})
9
+ * ]
10
+ * })
11
+ */
12
+ export declare function createMessageBundle(args: {
13
+ id: string;
14
+ messages: Message[];
15
+ alias?: MessageBundle["alias"];
16
+ }): MessageBundle;
17
+ /**
18
+ * create v2 Messsage AST with text-only pattern
19
+ * @example createMessage({locale: "en", text: "Hello world"})
20
+ */
21
+ export declare function createMessage(args: {
22
+ locale: LanguageTag;
23
+ text: string;
24
+ }): Message;
25
+ //# sourceMappingURL=createMessageBundle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createMessageBundle.d.ts","sourceRoot":"","sources":["../../src/v2/createMessageBundle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,OAAO,EAAQ,MAAM,YAAY,CAAA;AAEtE;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IACzC,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,EAAE,OAAO,EAAE,CAAA;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,CAAA;CAC9B,GAAG,aAAa,CAMhB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAOlF"}
@@ -0,0 +1,36 @@
1
+ import { LanguageTag, MessageBundle, Message, Text } from "./types.js";
2
+ /**
3
+ * create v2 MessageBundle
4
+ * @example createMessageBundle({
5
+ * id: "greeting",
6
+ * messages: [
7
+ * createMessage({locale: "en", text: "Hello world!"})
8
+ * createMessage({locale: "de", text: "Hallo Welt!"})
9
+ * ]
10
+ * })
11
+ */
12
+ export function createMessageBundle(args) {
13
+ return {
14
+ id: args.id,
15
+ alias: args.alias ?? {},
16
+ messages: args.messages,
17
+ };
18
+ }
19
+ /**
20
+ * create v2 Messsage AST with text-only pattern
21
+ * @example createMessage({locale: "en", text: "Hello world"})
22
+ */
23
+ export function createMessage(args) {
24
+ return {
25
+ locale: args.locale,
26
+ declarations: [],
27
+ selectors: [],
28
+ variants: [{ match: [], pattern: [toTextElement(args.text ?? "")] }],
29
+ };
30
+ }
31
+ function toTextElement(text) {
32
+ return {
33
+ type: "text",
34
+ value: text,
35
+ };
36
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=createMessageBundle.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createMessageBundle.test.d.ts","sourceRoot":"","sources":["../../src/v2/createMessageBundle.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,92 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { createMessageBundle, createMessage } from "./createMessageBundle.js";
3
+ import { MessageBundle } from "./types.js";
4
+ import { Value } from "@sinclair/typebox/value";
5
+ describe("createMessageBundle", () => {
6
+ it("creates a bundle with no messages", () => {
7
+ const bundle = createMessageBundle({ id: "no_messages", messages: [] });
8
+ expect(Value.Check(MessageBundle, bundle)).toBe(true);
9
+ expect(bundle).toEqual({
10
+ id: "no_messages",
11
+ alias: {},
12
+ messages: [],
13
+ });
14
+ });
15
+ it("creates a bundle with a single text-only message", () => {
16
+ const bundle = createMessageBundle({
17
+ id: "hello_world",
18
+ messages: [createMessage({ locale: "en", text: "Hello World!" })],
19
+ });
20
+ expect(Value.Check(MessageBundle, bundle)).toBe(true);
21
+ expect(bundle).toEqual({
22
+ id: "hello_world",
23
+ alias: {},
24
+ messages: [
25
+ {
26
+ locale: "en",
27
+ declarations: [],
28
+ selectors: [],
29
+ variants: [
30
+ {
31
+ match: [],
32
+ pattern: [
33
+ {
34
+ type: "text",
35
+ value: "Hello World!",
36
+ },
37
+ ],
38
+ },
39
+ ],
40
+ },
41
+ ],
42
+ });
43
+ });
44
+ it("creates a bundle with multiple text-only messages", () => {
45
+ const bundle = createMessageBundle({
46
+ id: "hello_world_2",
47
+ messages: [
48
+ createMessage({ locale: "en", text: "Hello World!" }),
49
+ createMessage({ locale: "de", text: "Hallo Welt!" }),
50
+ ],
51
+ });
52
+ expect(Value.Check(MessageBundle, bundle)).toBe(true);
53
+ expect(bundle).toEqual({
54
+ id: "hello_world_2",
55
+ alias: {},
56
+ messages: [
57
+ {
58
+ locale: "en",
59
+ declarations: [],
60
+ selectors: [],
61
+ variants: [
62
+ {
63
+ match: [],
64
+ pattern: [
65
+ {
66
+ type: "text",
67
+ value: "Hello World!",
68
+ },
69
+ ],
70
+ },
71
+ ],
72
+ },
73
+ {
74
+ locale: "de",
75
+ declarations: [],
76
+ selectors: [],
77
+ variants: [
78
+ {
79
+ match: [],
80
+ pattern: [
81
+ {
82
+ type: "text",
83
+ value: "Hallo Welt!",
84
+ },
85
+ ],
86
+ },
87
+ ],
88
+ },
89
+ ],
90
+ });
91
+ });
92
+ });
@@ -0,0 +1,3 @@
1
+ import type { MessageBundle } from "../../types.js";
2
+ export declare const bundle: MessageBundle;
3
+ //# sourceMappingURL=bundle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundle.d.ts","sourceRoot":"","sources":["../../../../src/v2/mocks/plural/bundle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAEnD,eAAO,MAAM,MAAM,EAAE,aA2IpB,CAAA"}
@@ -0,0 +1,140 @@
1
+ export const bundle = {
2
+ id: "mock_bundle_human_id",
3
+ alias: {
4
+ default: "mock_bundle_alias",
5
+ },
6
+ messages: [
7
+ {
8
+ locale: "de",
9
+ declarations: [
10
+ {
11
+ type: "input",
12
+ name: "numProducts",
13
+ value: {
14
+ type: "expression",
15
+ arg: {
16
+ type: "variable",
17
+ name: "numProducts",
18
+ },
19
+ },
20
+ },
21
+ ],
22
+ selectors: [
23
+ {
24
+ type: "expression",
25
+ arg: {
26
+ type: "variable",
27
+ name: "numProducts",
28
+ },
29
+ annotation: {
30
+ type: "function",
31
+ name: "plural",
32
+ options: [],
33
+ },
34
+ },
35
+ ],
36
+ variants: [
37
+ {
38
+ match: ["zero"],
39
+ pattern: [
40
+ {
41
+ type: "text",
42
+ value: "Keine Produkte",
43
+ },
44
+ ],
45
+ },
46
+ {
47
+ match: ["one"],
48
+ pattern: [
49
+ {
50
+ type: "text",
51
+ value: "Ein Produkt",
52
+ },
53
+ ],
54
+ },
55
+ {
56
+ match: ["other"],
57
+ pattern: [
58
+ {
59
+ type: "expression",
60
+ arg: {
61
+ type: "variable",
62
+ name: "numProducts",
63
+ },
64
+ },
65
+ {
66
+ type: "text",
67
+ value: " Produkte",
68
+ },
69
+ ],
70
+ },
71
+ ],
72
+ },
73
+ {
74
+ locale: "en",
75
+ declarations: [
76
+ {
77
+ type: "input",
78
+ name: "numProducts",
79
+ value: {
80
+ type: "expression",
81
+ arg: {
82
+ type: "variable",
83
+ name: "numProducts",
84
+ },
85
+ },
86
+ },
87
+ ],
88
+ selectors: [
89
+ {
90
+ type: "expression",
91
+ arg: {
92
+ type: "variable",
93
+ name: "numProducts",
94
+ },
95
+ annotation: {
96
+ type: "function",
97
+ name: "plural",
98
+ options: [],
99
+ },
100
+ },
101
+ ],
102
+ variants: [
103
+ {
104
+ match: ["zero"],
105
+ pattern: [
106
+ {
107
+ type: "text",
108
+ value: "No Products",
109
+ },
110
+ ],
111
+ },
112
+ {
113
+ match: ["one"],
114
+ pattern: [
115
+ {
116
+ type: "text",
117
+ value: "A product",
118
+ },
119
+ ],
120
+ },
121
+ {
122
+ match: ["other"],
123
+ pattern: [
124
+ {
125
+ type: "expression",
126
+ arg: {
127
+ type: "variable",
128
+ name: "numProducts",
129
+ },
130
+ },
131
+ {
132
+ type: "text",
133
+ value: " products",
134
+ },
135
+ ],
136
+ },
137
+ ],
138
+ },
139
+ ],
140
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=bundle.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundle.test.d.ts","sourceRoot":"","sources":["../../../../src/v2/mocks/plural/bundle.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,15 @@
1
+ /* eslint-disable @typescript-eslint/no-non-null-assertion */
2
+ import { describe, it, expect } from "vitest";
3
+ import { bundle } from "./bundle.js";
4
+ import { MessageBundle } from "../../types.js";
5
+ import { Value } from "@sinclair/typebox/value";
6
+ describe("mock plural messageBundle", () => {
7
+ it("is valid", () => {
8
+ const messageBundle = bundle;
9
+ expect(Value.Check(MessageBundle, messageBundle)).toBe(true);
10
+ expect(bundle.messages.length).toBe(2);
11
+ expect(bundle.messages[0].declarations.length).toBe(1);
12
+ expect(bundle.messages[0].selectors.length).toBe(1);
13
+ expect(bundle.messages[0].variants.length).toBe(3);
14
+ });
15
+ });