@dinoxx/dinox-cli 1.1.0 → 2.0.0

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 (111) hide show
  1. package/README.md +48 -4
  2. package/dist/cli.js +4 -0
  3. package/dist/commands/auth/index.js +1 -2
  4. package/dist/commands/boxes/index.js +37 -13
  5. package/dist/commands/boxes/operations.d.ts +3 -3
  6. package/dist/commands/boxes/operations.js +51 -28
  7. package/dist/commands/info/index.js +30 -5
  8. package/dist/commands/meta/repo.js +2 -1
  9. package/dist/commands/notes/actions.js +20 -37
  10. package/dist/commands/notes/bulk.d.ts +2 -2
  11. package/dist/commands/notes/bulk.js +3 -18
  12. package/dist/commands/notes/contentPatch.d.ts +5 -1
  13. package/dist/commands/notes/contentPatch.js +12 -1
  14. package/dist/commands/notes/contentPatchCommand.d.ts +3 -0
  15. package/dist/commands/notes/contentPatchCommand.js +29 -8
  16. package/dist/commands/notes/descriptors.js +19 -16
  17. package/dist/commands/notes/export.js +3 -0
  18. package/dist/commands/notes/repo.d.ts +9 -0
  19. package/dist/commands/notes/repo.js +65 -15
  20. package/dist/commands/notes/searchOutput.d.ts +2 -1
  21. package/dist/commands/notes/searchOutput.js +2 -1
  22. package/dist/commands/notes/searchSql.js +9 -3
  23. package/dist/commands/prompt/index.d.ts +1 -0
  24. package/dist/commands/prompt/index.js +26 -11
  25. package/dist/commands/runtime.js +17 -6
  26. package/dist/commands/savedViews/index.d.ts +7 -0
  27. package/dist/commands/savedViews/index.js +458 -0
  28. package/dist/commands/savedViews/model.d.ts +87 -0
  29. package/dist/commands/savedViews/model.js +306 -0
  30. package/dist/commands/savedViews/repo.d.ts +123 -0
  31. package/dist/commands/savedViews/repo.js +512 -0
  32. package/dist/commands/savedViews/semantics.d.ts +46 -0
  33. package/dist/commands/savedViews/semantics.js +738 -0
  34. package/dist/commands/schema/renderSkills.d.ts +2 -0
  35. package/dist/commands/schema/renderSkills.js +69 -10
  36. package/dist/commands/schema/spec.js +4 -0
  37. package/dist/commands/skills/index.d.ts +54 -0
  38. package/dist/commands/skills/index.js +468 -0
  39. package/dist/commands/storage/index.js +2 -2
  40. package/dist/commands/sync.d.ts +23 -1
  41. package/dist/commands/sync.js +100 -58
  42. package/dist/commands/tags/index.js +30 -11
  43. package/dist/commands/tags/operations.d.ts +3 -3
  44. package/dist/commands/tags/operations.js +45 -20
  45. package/dist/commands/templates/model.d.ts +50 -0
  46. package/dist/commands/templates/model.js +239 -0
  47. package/dist/commands/todo/index.js +3 -3
  48. package/dist/commands/update.d.ts +1 -0
  49. package/dist/commands/update.js +46 -9
  50. package/dist/commands/writeConfirmation.d.ts +13 -0
  51. package/dist/commands/writeConfirmation.js +54 -0
  52. package/dist/config/resolve.js +5 -10
  53. package/dist/config/types.d.ts +3 -6
  54. package/dist/constants/links.d.ts +18 -1
  55. package/dist/constants/links.js +26 -1
  56. package/dist/daemon/client.d.ts +2 -2
  57. package/dist/daemon/client.js +106 -52
  58. package/dist/daemon/index.d.ts +5 -3
  59. package/dist/daemon/index.js +28 -5
  60. package/dist/daemon/lifecycle.d.ts +10 -3
  61. package/dist/daemon/lifecycle.js +54 -11
  62. package/dist/daemon/pid.d.ts +1 -1
  63. package/dist/daemon/pid.js +6 -3
  64. package/dist/dinox.js +9 -1
  65. package/dist/powersync/exclusiveRuntime.d.ts +2 -0
  66. package/dist/powersync/exclusiveRuntime.js +28 -4
  67. package/dist/powersync/runtime.d.ts +4 -2
  68. package/dist/powersync/runtime.js +43 -5
  69. package/dist/powersync/schema/content.d.ts +1 -78
  70. package/dist/powersync/schema/content.js +1 -78
  71. package/dist/powersync/schema/electronCanonical.d.ts +1561 -0
  72. package/dist/powersync/schema/electronCanonical.js +1154 -0
  73. package/dist/powersync/schema/index.d.ts +573 -129
  74. package/dist/powersync/schema/index.js +3 -32
  75. package/dist/powersync/schema/local.d.ts +1 -56
  76. package/dist/powersync/schema/local.js +1 -60
  77. package/dist/powersync/schema/note.d.ts +1 -35
  78. package/dist/powersync/schema/note.js +1 -35
  79. package/dist/powersync/schema/notesExtras.d.ts +1 -62
  80. package/dist/powersync/schema/notesExtras.js +1 -71
  81. package/dist/powersync/schema/projects.d.ts +1 -104
  82. package/dist/powersync/schema/projects.js +1 -104
  83. package/dist/powersync/schema/savedViews.d.ts +1 -0
  84. package/dist/powersync/schema/savedViews.js +1 -0
  85. package/dist/powersync/schema/storage.d.ts +1 -24
  86. package/dist/powersync/schema/storage.js +1 -24
  87. package/dist/powersync/schema/tags.d.ts +1 -37
  88. package/dist/powersync/schema/tags.js +1 -37
  89. package/dist/powersync/syncGate.d.ts +22 -3
  90. package/dist/powersync/syncGate.js +4 -1
  91. package/dist/powersync/syncPass.d.ts +2 -0
  92. package/dist/powersync/syncPass.js +15 -4
  93. package/dist/powersync/tokenIndex.d.ts +2 -0
  94. package/dist/powersync/tokenIndex.js +60 -18
  95. package/dist/powersync/uploader.d.ts +16 -2
  96. package/dist/powersync/uploader.js +152 -158
  97. package/dist/skills/check.d.ts +1 -0
  98. package/dist/skills/check.js +538 -70
  99. package/dist/skills/retired.d.ts +60 -0
  100. package/dist/skills/retired.js +58 -0
  101. package/dist/utils/deadline.d.ts +8 -0
  102. package/dist/utils/deadline.js +31 -0
  103. package/dist/utils/dryRun.d.ts +20 -1
  104. package/dist/utils/dryRun.js +22 -3
  105. package/dist/utils/errors.d.ts +2 -0
  106. package/dist/utils/errors.js +5 -3
  107. package/dist/utils/processExit.d.ts +1 -0
  108. package/dist/utils/processExit.js +33 -0
  109. package/dist/utils/updateNotice.d.ts +1 -0
  110. package/dist/utils/updateNotice.js +1 -1
  111. package/package.json +10 -5
@@ -1,4 +1,6 @@
1
1
  import { withDaemonExclusiveAccess } from '../daemon/lifecycle.js';
2
+ import { runWithinDeadline, remainingDeadlineMs } from '../utils/deadline.js';
3
+ import { DinoxError } from '../utils/errors.js';
2
4
  import { printHumanReadableWarning } from '../utils/output.js';
3
5
  import { closePowerSyncAndReleaseOwner, connectPowerSync, } from './runtime.js';
4
6
  const exclusivePowerSyncDependencies = {
@@ -10,11 +12,25 @@ const exclusivePowerSyncDependencies = {
10
12
  function errorMessage(error) {
11
13
  return error instanceof Error ? error.message : String(error);
12
14
  }
15
+ function createRuntimeCleanupDeadlineError() {
16
+ return new DinoxError('Sync deadline exceeded while closing the local PowerSync runtime.', {
17
+ code: 'SYNC_TIMEOUT',
18
+ details: { phase: 'powersync-cleanup' },
19
+ suggestion: 'Run `dino doctor --format json` to verify the local runtime before retrying sync.',
20
+ recoverable: true,
21
+ requiresProcessExit: true,
22
+ });
23
+ }
13
24
  export async function withExclusivePowerSync(args, run, overrides = {}) {
14
25
  const dependencies = { ...exclusivePowerSyncDependencies, ...overrides };
15
- const { cleanupFailureMode, ...connectArgs } = args;
16
- return dependencies.withDaemonExclusiveAccess(args.config, args.timeoutMs, async (daemonLifecycle) => {
17
- const connected = await dependencies.connectPowerSync(connectArgs);
26
+ const { cleanupFailureMode, deadlineAtMs, operationDeadlineAtMs = deadlineAtMs, ...connectArgs } = args;
27
+ const remainingOperationTimeoutMs = () => Math.max(1, remainingDeadlineMs(operationDeadlineAtMs, args.timeoutMs));
28
+ const remainingTotalTimeoutMs = () => Math.max(1, remainingDeadlineMs(deadlineAtMs, args.timeoutMs));
29
+ return dependencies.withDaemonExclusiveAccess(args.config, remainingTotalTimeoutMs(), async (daemonLifecycle) => {
30
+ const connected = await dependencies.connectPowerSync({
31
+ ...connectArgs,
32
+ timeoutMs: remainingOperationTimeoutMs(),
33
+ });
18
34
  let outcome;
19
35
  try {
20
36
  outcome = { ok: true, value: await run(connected) };
@@ -24,7 +40,11 @@ export async function withExclusivePowerSync(args, run, overrides = {}) {
24
40
  }
25
41
  let cleanupError;
26
42
  try {
27
- await dependencies.closePowerSyncAndReleaseOwner(connected.db, connected.releaseOwner);
43
+ await runWithinDeadline(() => dependencies.closePowerSyncAndReleaseOwner(connected.db, connected.releaseOwner), {
44
+ deadlineAtMs,
45
+ maximumTimeoutMs: args.timeoutMs,
46
+ createTimeoutError: createRuntimeCleanupDeadlineError,
47
+ });
28
48
  }
29
49
  catch (error) {
30
50
  cleanupError = error;
@@ -38,5 +58,9 @@ export async function withExclusivePowerSync(args, run, overrides = {}) {
38
58
  throw cleanupError;
39
59
  }
40
60
  return outcome.value;
61
+ }, {}, {
62
+ deadlineAtMs,
63
+ operationDeadlineAtMs,
64
+ cleanupFailureMode,
41
65
  });
42
66
  }
@@ -1,6 +1,7 @@
1
1
  import { PowerSyncDatabase } from '@powersync/node';
2
- import type { AbstractPowerSyncDatabase, SyncStatusOptions } from '@powersync/common';
2
+ import type { AbstractPowerSyncDatabase } from '@powersync/common';
3
3
  import type { ResolvedDinoxConfig } from '../config/types.js';
4
+ import type { SyncStatusRaw } from './syncGate.js';
4
5
  export type ConnectResult = {
5
6
  db: PowerSyncDatabase;
6
7
  dbPath: string;
@@ -29,7 +30,7 @@ export declare function getStatusSnapshot(db: AbstractPowerSyncDatabase): {
29
30
  message: string;
30
31
  };
31
32
  };
32
- raw: SyncStatusOptions;
33
+ raw: SyncStatusRaw;
33
34
  };
34
35
  export declare function connectPowerSync(args: {
35
36
  config: ResolvedDinoxConfig;
@@ -39,6 +40,7 @@ export declare function connectPowerSync(args: {
39
40
  expectedTokenFingerprint?: string | null;
40
41
  }): Promise<ConnectResult>;
41
42
  export declare function waitForIdleDataFlow(db: AbstractPowerSyncDatabase, timeoutMs: number): Promise<boolean>;
43
+ export declare function waitForDownloadIdle(db: AbstractPowerSyncDatabase, timeoutMs: number): Promise<boolean>;
42
44
  export declare function waitForLastSyncedAfter(db: AbstractPowerSyncDatabase, startedAtIso: string, timeoutMs: number): Promise<boolean>;
43
45
  export type UploadQueueWaitResult = {
44
46
  ok: boolean;
@@ -88,8 +88,25 @@ async function ensureDataDir() {
88
88
  await fs.mkdir(dir, { recursive: true, mode: 0o700 });
89
89
  return dir;
90
90
  }
91
+ function readSyncStatus(status) {
92
+ if (!status)
93
+ return {};
94
+ return {
95
+ connected: status.connected,
96
+ connecting: status.connecting,
97
+ hasSynced: status.hasSynced,
98
+ lastSyncedAt: status.lastSyncedAt,
99
+ dataFlow: {
100
+ downloading: status.downloading,
101
+ uploading: status.uploading,
102
+ downloadError: status.downloadError,
103
+ uploadError: status.uploadError,
104
+ },
105
+ priorityStatusEntries: status.priorityStatusEntries,
106
+ };
107
+ }
91
108
  export function getStatusSnapshot(db) {
92
- const raw = db.currentStatus?.toJSON?.() ?? {};
109
+ const raw = readSyncStatus(db.currentStatus);
93
110
  const lastSyncedAt = raw.lastSyncedAt instanceof Date ? raw.lastSyncedAt.toISOString() : raw.lastSyncedAt ?? null;
94
111
  const dataFlow = raw.dataFlow ?? {};
95
112
  return {
@@ -185,8 +202,7 @@ export async function connectPowerSync(args) {
185
202
  ? createPowerSyncUploadHandler({
186
203
  authorization: args.config.auth.authorization,
187
204
  uploadBaseUrl: args.config.powersync.uploadBaseUrl,
188
- uploadV4Path: args.config.powersync.uploadV4Path,
189
- uploadV2Path: args.config.powersync.uploadV2Path,
205
+ uploadPath: args.config.powersync.uploadPath,
190
206
  timeoutMs: args.timeoutMs,
191
207
  })
192
208
  : undefined;
@@ -239,13 +255,33 @@ export async function waitForIdleDataFlow(db, timeoutMs) {
239
255
  cancel();
240
256
  }
241
257
  }
258
+ export async function waitForDownloadIdle(db, timeoutMs) {
259
+ const { signal, cancel } = createTimeoutSignal(timeoutMs);
260
+ try {
261
+ await db.waitForStatus(status => {
262
+ const flow = status.dataFlowStatus;
263
+ return Boolean(status.connected) && Boolean(status.hasSynced) && !flow.downloading;
264
+ }, signal);
265
+ return !signal.aborted;
266
+ }
267
+ catch {
268
+ return false;
269
+ }
270
+ finally {
271
+ cancel();
272
+ }
273
+ }
242
274
  export async function waitForLastSyncedAfter(db, startedAtIso, timeoutMs) {
243
275
  const startedAtMs = Date.parse(startedAtIso);
244
276
  if (!Number.isFinite(startedAtMs)) {
245
277
  return false;
246
278
  }
279
+ // PowerSync reports checkpoint timestamps with whole-second precision.
280
+ const startedAtCheckpointPrecisionMs = Math.floor(startedAtMs / 1_000) * 1_000;
247
281
  const status = getStatusSnapshot(db);
248
- if (status.connected && status.lastSyncedAt && Date.parse(status.lastSyncedAt) >= startedAtMs) {
282
+ if (status.connected
283
+ && status.lastSyncedAt
284
+ && Date.parse(status.lastSyncedAt) >= startedAtCheckpointPrecisionMs) {
249
285
  return true;
250
286
  }
251
287
  const { signal, cancel } = createTimeoutSignal(timeoutMs);
@@ -253,7 +289,9 @@ export async function waitForLastSyncedAfter(db, startedAtIso, timeoutMs) {
253
289
  await db.waitForStatus((nextStatus) => {
254
290
  const value = nextStatus.lastSyncedAt;
255
291
  const lastSyncedAt = value instanceof Date ? value.toISOString() : value ?? null;
256
- return Boolean(nextStatus.connected && lastSyncedAt && Date.parse(lastSyncedAt) >= startedAtMs);
292
+ return Boolean(nextStatus.connected
293
+ && lastSyncedAt
294
+ && Date.parse(lastSyncedAt) >= startedAtCheckpointPrecisionMs);
257
295
  }, signal);
258
296
  return !signal.aborted;
259
297
  }
@@ -1,78 +1 @@
1
- import { Table } from '@powersync/common';
2
- export declare const c_card_box: Table<{
3
- id: import("@powersync/common").BaseColumnType<string | null>;
4
- name: import("@powersync/common").BaseColumnType<string | null>;
5
- type: import("@powersync/common").BaseColumnType<string | null>;
6
- cover_url: import("@powersync/common").BaseColumnType<string | null>;
7
- prompt: import("@powersync/common").BaseColumnType<string | null>;
8
- headers: import("@powersync/common").BaseColumnType<string | null>;
9
- priority: import("@powersync/common").BaseColumnType<number | null>;
10
- created_at: import("@powersync/common").BaseColumnType<string | null>;
11
- updated_at: import("@powersync/common").BaseColumnType<string | null>;
12
- extra_data: import("@powersync/common").BaseColumnType<string | null>;
13
- user_no: import("@powersync/common").BaseColumnType<string | null>;
14
- is_del: import("@powersync/common").BaseColumnType<number | null>;
15
- template_id: import("@powersync/common").BaseColumnType<string | null>;
16
- }>;
17
- export declare const c_card_note: Table<{
18
- id: import("@powersync/common").BaseColumnType<string | null>;
19
- box_id: import("@powersync/common").BaseColumnType<string | null>;
20
- content: import("@powersync/common").BaseColumnType<string | null>;
21
- created_at: import("@powersync/common").BaseColumnType<string | null>;
22
- updated_at: import("@powersync/common").BaseColumnType<string | null>;
23
- extra_data: import("@powersync/common").BaseColumnType<string | null>;
24
- user_no: import("@powersync/common").BaseColumnType<string | null>;
25
- is_del: import("@powersync/common").BaseColumnType<number | null>;
26
- origin_note_id: import("@powersync/common").BaseColumnType<string | null>;
27
- origin_type: import("@powersync/common").BaseColumnType<string | null>;
28
- output_type: import("@powersync/common").BaseColumnType<string | null>;
29
- is_array: import("@powersync/common").BaseColumnType<number | null>;
30
- }>;
31
- export declare const c_cmd: Table<{
32
- id: import("@powersync/common").BaseColumnType<string | null>;
33
- zone: import("@powersync/common").BaseColumnType<string | null>;
34
- type: import("@powersync/common").BaseColumnType<string | null>;
35
- cmd: import("@powersync/common").BaseColumnType<string | null>;
36
- name: import("@powersync/common").BaseColumnType<string | null>;
37
- priority: import("@powersync/common").BaseColumnType<number | null>;
38
- is_show: import("@powersync/common").BaseColumnType<number | null>;
39
- description: import("@powersync/common").BaseColumnType<string | null>;
40
- extra_data: import("@powersync/common").BaseColumnType<string | null>;
41
- user_id: import("@powersync/common").BaseColumnType<string | null>;
42
- insert_at: import("@powersync/common").BaseColumnType<string | null>;
43
- update_at: import("@powersync/common").BaseColumnType<string | null>;
44
- is_del: import("@powersync/common").BaseColumnType<number | null>;
45
- template_id: import("@powersync/common").BaseColumnType<string | null>;
46
- meta_data: import("@powersync/common").BaseColumnType<string | null>;
47
- output: import("@powersync/common").BaseColumnType<string | null>;
48
- output_param: import("@powersync/common").BaseColumnType<string | null>;
49
- category: import("@powersync/common").BaseColumnType<string | null>;
50
- }>;
51
- export declare const c_note_template: Table<{
52
- id: import("@powersync/common").BaseColumnType<string | null>;
53
- content: import("@powersync/common").BaseColumnType<string | null>;
54
- name: import("@powersync/common").BaseColumnType<string | null>;
55
- priority: import("@powersync/common").BaseColumnType<number | null>;
56
- is_show: import("@powersync/common").BaseColumnType<number | null>;
57
- extra_data: import("@powersync/common").BaseColumnType<string | null>;
58
- user_id: import("@powersync/common").BaseColumnType<string | null>;
59
- insert_at: import("@powersync/common").BaseColumnType<string | null>;
60
- update_at: import("@powersync/common").BaseColumnType<string | null>;
61
- is_del: import("@powersync/common").BaseColumnType<number | null>;
62
- }>;
63
- export declare const c_zettel_box: Table<{
64
- id: import("@powersync/common").BaseColumnType<string | null>;
65
- name: import("@powersync/common").BaseColumnType<string | null>;
66
- path: import("@powersync/common").BaseColumnType<string | null>;
67
- parent_id: import("@powersync/common").BaseColumnType<string | null>;
68
- description: import("@powersync/common").BaseColumnType<string | null>;
69
- color: import("@powersync/common").BaseColumnType<string | null>;
70
- priority: import("@powersync/common").BaseColumnType<number | null>;
71
- is_show: import("@powersync/common").BaseColumnType<number | null>;
72
- cover_url: import("@powersync/common").BaseColumnType<string | null>;
73
- created_at: import("@powersync/common").BaseColumnType<string | null>;
74
- updated_at: import("@powersync/common").BaseColumnType<string | null>;
75
- extra_data: import("@powersync/common").BaseColumnType<string | null>;
76
- user_no: import("@powersync/common").BaseColumnType<string | null>;
77
- is_del: import("@powersync/common").BaseColumnType<number | null>;
78
- }>;
1
+ export { c_card_box, c_card_note, c_cmd, c_note_template, c_zettel_box, } from './electronCanonical.js';
@@ -1,78 +1 @@
1
- import { column, Table } from '@powersync/common';
2
- export const c_card_box = new Table({
3
- id: column.text,
4
- name: column.text,
5
- type: column.text,
6
- cover_url: column.text,
7
- prompt: column.text,
8
- headers: column.text,
9
- priority: column.integer,
10
- created_at: column.text,
11
- updated_at: column.text,
12
- extra_data: column.text,
13
- user_no: column.text,
14
- is_del: column.integer,
15
- template_id: column.text,
16
- });
17
- export const c_card_note = new Table({
18
- id: column.text,
19
- box_id: column.text,
20
- content: column.text,
21
- created_at: column.text,
22
- updated_at: column.text,
23
- extra_data: column.text,
24
- user_no: column.text,
25
- is_del: column.integer,
26
- origin_note_id: column.text,
27
- origin_type: column.text,
28
- output_type: column.text,
29
- is_array: column.integer,
30
- });
31
- export const c_cmd = new Table({
32
- id: column.text,
33
- zone: column.text,
34
- type: column.text,
35
- cmd: column.text,
36
- name: column.text,
37
- priority: column.integer,
38
- is_show: column.integer,
39
- description: column.text,
40
- extra_data: column.text,
41
- user_id: column.text,
42
- insert_at: column.text,
43
- update_at: column.text,
44
- is_del: column.integer,
45
- template_id: column.text,
46
- meta_data: column.text,
47
- output: column.text,
48
- output_param: column.text,
49
- category: column.text,
50
- });
51
- export const c_note_template = new Table({
52
- id: column.text,
53
- content: column.text,
54
- name: column.text,
55
- priority: column.integer,
56
- is_show: column.integer,
57
- extra_data: column.text,
58
- user_id: column.text,
59
- insert_at: column.text,
60
- update_at: column.text,
61
- is_del: column.integer,
62
- });
63
- export const c_zettel_box = new Table({
64
- id: column.text,
65
- name: column.text,
66
- path: column.text,
67
- parent_id: column.text,
68
- description: column.text,
69
- color: column.text,
70
- priority: column.integer,
71
- is_show: column.integer,
72
- cover_url: column.text,
73
- created_at: column.text,
74
- updated_at: column.text,
75
- extra_data: column.text,
76
- user_no: column.text,
77
- is_del: column.integer,
78
- });
1
+ export { c_card_box, c_card_note, c_cmd, c_note_template, c_zettel_box, } from './electronCanonical.js';