@arrai-innovations/reactive-helpers 17.0.0 → 17.0.2

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.
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { execSync } from "child_process";
4
+ import fs from "fs";
5
+ import os from "os";
6
+ import path from "path";
7
+ import { fileURLToPath } from "url";
8
+
9
+ const __filename = fileURLToPath(import.meta.url);
10
+ const scriptName = path.basename(__filename);
11
+
12
+ const BLUE_COLOR = "\u001b[1;38;2;0;119;247m";
13
+ const ORANGE_COLOR = "\u001b[1;38;2;255;127;0m";
14
+ const RESET_COLOR = "\u001b[0m";
15
+
16
+ const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "docs-"));
17
+ const docsDir = path.resolve("./docs");
18
+
19
+ function cleanup() {
20
+ fs.rmSync(tempDir, { recursive: true, force: true });
21
+ }
22
+
23
+ process.on("exit", cleanup);
24
+ process.on("SIGINT", () => {
25
+ cleanup();
26
+ process.exit(1);
27
+ });
28
+
29
+ execSync(`npx --no-install typedoc --out "${tempDir}" --plugin typedoc-plugin-markdown --disableSources`, {
30
+ stdio: "inherit",
31
+ });
32
+
33
+ let docsAreDifferent = false;
34
+
35
+ try {
36
+ execSync(`git diff --no-index --quiet "${tempDir}" "${docsDir}"`, {
37
+ stdio: "inherit",
38
+ });
39
+ } catch (error) {
40
+ if (error.status === 1) {
41
+ // Differences found
42
+ docsAreDifferent = true;
43
+ } else {
44
+ // Unexpected error
45
+ throw error;
46
+ }
47
+ }
48
+
49
+ if (docsAreDifferent) {
50
+ console.log(`[${scriptName}] ${ORANGE_COLOR}Docs are out of date, updating...${RESET_COLOR}`);
51
+ fs.rmSync("./docs", { recursive: true, force: true });
52
+ fs.renameSync(tempDir, "./docs");
53
+ execSync(`git add ./docs`, { stdio: "inherit" });
54
+ } else {
55
+ console.log(`[${scriptName}] ${BLUE_COLOR}Docs are up to date${RESET_COLOR}`);
56
+ }
57
+
58
+ cleanup();
59
+ process.exit(0);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arrai-innovations/reactive-helpers",
3
- "version": "17.0.0",
3
+ "version": "17.0.2",
4
4
  "description": "VueJS 3 utility composition functions to help manipulate objects and lists.",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -10,13 +10,13 @@
10
10
  "tests": "tests"
11
11
  },
12
12
  "scripts": {
13
- "test": "vitest",
13
+ "test": "npx vitest",
14
14
  "eslint": "npx --no-install eslint --fix index.js config/**/*.js tests/**/*.js use/**/*.js utils/**/*.js",
15
15
  "prettier": "npx --no-install prettier --write .",
16
16
  "coverage": "npm run coverage:clean; npm test -- --coverage=true",
17
17
  "coverage:clean": "rm -rf coverage",
18
- "prepare": "husky || true",
19
- "docs": "./makeTypeDoc.sh"
18
+ "prepare": "npx --no-install husky",
19
+ "docs": "node make_type_doc.js"
20
20
  },
21
21
  "repository": {
22
22
  "type": "git",
@@ -32,12 +32,12 @@
32
32
  "@arrai-innovations/commitlint-config": "^1.1.0",
33
33
  "@commitlint/cli": "^19.4.0",
34
34
  "@godaddy/dmd": "^1.0.4",
35
- "@trivago/prettier-plugin-sort-imports": "^4.3.0",
35
+ "@trivago/prettier-plugin-sort-imports": "^5.2.1",
36
36
  "@types/browser-util-inspect": "^0.2.4",
37
37
  "@types/lodash-es": "^4.17.12",
38
38
  "@typescript-eslint/eslint-plugin": "^7.18.0",
39
39
  "@typescript-eslint/parser": "^7.18.0",
40
- "@vitest/coverage-v8": "^1.6.0",
40
+ "@vitest/coverage-v8": "^2.1.8",
41
41
  "@vue/compiler-sfc": "^3.4.37",
42
42
  "@vue/eslint-config-prettier": "^9.0.0",
43
43
  "@vue/test-utils": "^2.3.2",
@@ -48,24 +48,24 @@
48
48
  "eslint-plugin-vitest-globals": "^1.3.1",
49
49
  "eslint-plugin-vue": "^9.27.0",
50
50
  "flush-promises": "^1.0.2",
51
- "globals": "^15.9.0",
52
- "jsdom": "^24.1.1",
51
+ "globals": "^15.14.0",
52
+ "husky": "^9.1.7",
53
+ "jsdom": "^26.0.0",
53
54
  "lint-staged": "^15.2.8",
54
55
  "prettier": "^3.3.3",
55
56
  "typedoc": "^0.27.1",
56
57
  "typedoc-plugin-markdown": "^4.3.0",
57
58
  "typescript": "^5.5.4",
58
- "vitest": "^1.6.0"
59
+ "vitest": "^2.1.8"
59
60
  },
60
61
  "dependencies": {
61
62
  "@jcoreio/async-throttle": "^1.6.0",
62
63
  "browser-util-inspect": "^0.2.0",
63
64
  "flexsearch": "0.7.21",
64
- "husky": "^9.0.11",
65
65
  "vue-deepunref": "^1.0.1"
66
66
  },
67
67
  "peerDependencies": {
68
- "@vueuse/core": "^11.2.0",
68
+ "@vueuse/core": "^12.4.0",
69
69
  "lodash-es": "^4.17.21",
70
70
  "vue": "^3.4.30"
71
71
  }
@@ -1,4 +1,4 @@
1
- import { doAwaitNot } from "../../../utils/watches.js";
1
+ import { doAwaitNot, doAwaitTimeout } from "../../../utils/watches.js";
2
2
  import { expectErrorToBeNull } from "../expectHelpers.js";
3
3
  import flushPromises from "flush-promises";
4
4
  import keyBy from "lodash-es/keyBy.js";
@@ -274,30 +274,38 @@ describe("use/listInstance.spec.js", function () {
274
274
  expect({ ...listInstance.state.objects }).toEqual({});
275
275
  });
276
276
  it("already loading", async function () {
277
- const listArgs = reactive({
278
- user: 1,
279
- });
280
- const retrieveArgs = reactive({
281
- fields,
282
- });
277
+ const listArgs = reactive({ user: 1 });
278
+ const retrieveArgs = reactive({ fields });
283
279
  const listInstance = useListInstance({
284
280
  props: { pkKey: "id", listArgs, retrieveArgs },
285
281
  keepOldPages: false,
286
282
  });
283
+
287
284
  expectErrorToBeNull(listInstance.state.error);
288
285
  expect(listInstance.state.errored).toBe(false);
289
286
  expect(listInstance.state.loading).toBeUndefined();
290
- expect({ ...listInstance.state.objects }).toEqual({});
291
- globalList.mockImplementation(() => new Promise(() => {}));
287
+
288
+ let bulkDeleteResolve;
289
+ const bulkDeletePromise = new Promise((resolve) => {
290
+ bulkDeleteResolve = resolve;
291
+ });
292
+ globalBulkDelete.mockImplementation(() => bulkDeletePromise);
292
293
  listInstance.bulkDelete();
293
294
 
294
- expectErrorToBeNull(listInstance.state.error);
295
- expect(listInstance.state.errored).toBe(false);
296
295
  expect(listInstance.state.loading).toBe(true);
296
+
297
297
  await expect(() => listInstance.list()).rejects.toThrow(ListInstanceError);
298
+
299
+ expect(listInstance.state.loading).toBe(true);
300
+
301
+ // @ts-ignore - bulkDeleteResolve is set in a promise. promise executors run immediately
302
+ bulkDeleteResolve();
303
+ await flushPromises();
304
+
305
+ expect(globalBulkDelete).toHaveBeenCalledTimes(1);
298
306
  expectErrorToBeNull(listInstance.state.error);
299
307
  expect(listInstance.state.errored).toBe(false);
300
- expect(listInstance.state.loading).toBe(true);
308
+ expect(listInstance.state.loading).toBe(false);
301
309
  });
302
310
  it("errored", async function () {
303
311
  const listArgs = reactive({
@@ -463,6 +463,10 @@ export function useListInstance({ props, functions = {}, keepOldPages }) {
463
463
 
464
464
  function clearList() {
465
465
  assignReactiveObject(state.objects, {});
466
+ // to avoid objectsInOrderRefs from being in a broken state
467
+ // for a tick or two, where all the elements are undefined
468
+ // we need to clear it as well
469
+ objectsInOrderRefs.value = [];
466
470
  loadingError.clearError();
467
471
  }
468
472
 
package/utils/classes.js CHANGED
@@ -176,5 +176,13 @@ export const stringifyClass = (cls) => {
176
176
  .filter((key) => unref(/** @type {boolean | import('vue').Ref<boolean>} */ (cls[key])))
177
177
  .join(" ");
178
178
  }
179
+ if (isString(cls)) {
180
+ const arrayish = cls.split(/\s+/);
181
+ const unique = new Set(arrayish);
182
+ if (unique.size === arrayish.length) {
183
+ return cls;
184
+ }
185
+ return [...unique].join(" ");
186
+ }
179
187
  return cls;
180
188
  };