@lapis-notes/api 0.1.0 → 0.1.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.
- package/CHANGELOG.md +18 -0
- package/README.md +5 -0
- package/dist/app-database-host.d.ts +1 -0
- package/dist/app-database-host.js +1 -0
- package/dist/browser-sync-security.d.ts +45 -0
- package/dist/browser-sync-security.js +189 -0
- package/dist/build-tools/vite.d.ts +15 -0
- package/dist/build-tools/vite.js +36 -0
- package/dist/cache.svelte.d.ts +1 -1
- package/dist/cache.svelte.js +4 -1
- package/dist/components/editor/editor.css +54 -2
- package/dist/components/editor/extensions/lint/lapis-lint-tooltip.svelte +18 -5
- package/dist/components/editor/extensions/lint/lint-tooltip-actions.d.ts +0 -2
- package/dist/components/editor/extensions/lint/lint-tooltip-actions.js +0 -14
- package/dist/components/editor/language-service/index.js +23 -2
- package/dist/components/icon/icon-list.svelte.d.ts +1 -1
- package/dist/components/select/select.svelte.d.ts +1 -1
- package/dist/context.svelte.d.ts +11 -1
- package/dist/context.svelte.js +38 -1
- package/dist/docs-api.d.ts +2 -0
- package/dist/docs-api.js +1 -0
- package/dist/generated/plugin-host-modules.schema.generated.d.ts +443 -13
- package/dist/generated/plugin-host-modules.schema.generated.js +970 -306
- package/dist/index.d.ts +5 -0
- package/dist/index.js +5 -0
- package/dist/language-service/manager.d.ts +5 -0
- package/dist/language-service/manager.js +58 -14
- package/dist/lapis-extension.d.ts +1 -1
- package/dist/lapis-extension.js +12 -0
- package/dist/nostr-signer.d.ts +68 -0
- package/dist/nostr-signer.js +49 -0
- package/dist/plugin-asset-server.d.ts +1 -0
- package/dist/plugin-asset-server.js +3 -0
- package/dist/plugin-capability-facade.d.ts +1 -1
- package/dist/plugin-capability-facade.js +6 -0
- package/dist/plugin-distribution/catalog-media.d.ts +4 -0
- package/dist/plugin-distribution/catalog-media.js +40 -0
- package/dist/plugin-distribution/download-stats.d.ts +4 -0
- package/dist/plugin-distribution/download-stats.js +19 -0
- package/dist/plugin-distribution/index.d.ts +4 -0
- package/dist/plugin-distribution/index.js +4 -0
- package/dist/plugin-distribution/installer.d.ts +3 -0
- package/dist/plugin-distribution/installer.js +9 -2
- package/dist/plugin-distribution/manager.d.ts +71 -5
- package/dist/plugin-distribution/manager.js +376 -37
- package/dist/plugin-distribution/nostr-registry-adapter.d.ts +29 -0
- package/dist/plugin-distribution/nostr-registry-adapter.js +152 -0
- package/dist/plugin-distribution/plugin-bundle-verifier.d.ts +43 -0
- package/dist/plugin-distribution/plugin-bundle-verifier.js +64 -1
- package/dist/plugin-distribution/plugin-bundle.d.ts +14 -0
- package/dist/plugin-distribution/plugin-bundle.js +46 -7
- package/dist/plugin-distribution/plugin-markdown.d.ts +6 -0
- package/dist/plugin-distribution/plugin-markdown.js +94 -0
- package/dist/plugin-distribution/registry-client.d.ts +6 -1
- package/dist/plugin-distribution/registry-client.js +32 -10
- package/dist/plugin-distribution/registry-source-state.d.ts +15 -0
- package/dist/plugin-distribution/registry-source-state.js +42 -0
- package/dist/plugin-distribution/schemas.d.ts +2511 -2824
- package/dist/plugin-distribution/schemas.js +111 -42
- package/dist/plugin-distribution/types.d.ts +116 -5
- package/dist/plugin-distribution-host.d.ts +4 -0
- package/dist/plugin-distribution-host.js +2 -0
- package/dist/plugin-install-progress.js +1 -1
- package/dist/plugin-manager.d.ts +3 -0
- package/dist/plugin-manager.js +21 -13
- package/dist/plugin-settings.d.ts +21 -0
- package/dist/plugin-settings.js +41 -0
- package/dist/plugin.d.ts +13 -0
- package/dist/plugin.js +56 -0
- package/dist/registry-schema/catalog-v1.d.ts +4143 -0
- package/dist/registry-schema/catalog-v1.js +172 -0
- package/dist/registry-schema/catalog-v2.d.ts +5275 -0
- package/dist/registry-schema/catalog-v2.js +137 -0
- package/dist/registry-schema/index.d.ts +1 -0
- package/dist/registry-schema/index.js +1 -0
- package/dist/registry-schema/release-notes.d.ts +5 -0
- package/dist/registry-schema/release-notes.js +21 -0
- package/dist/server-host.d.ts +28 -0
- package/dist/server-host.js +17 -0
- package/dist/storage/app-database.d.ts +37 -2
- package/dist/storage/app-database.js +41 -1
- package/dist/storage/browser-coordinated-app-database.d.ts +3 -1
- package/dist/storage/browser-coordinated-app-database.js +8 -0
- package/dist/storage/browser.d.ts +4 -1
- package/dist/storage/browser.js +84 -0
- package/dist/storage/desktop-native.d.ts +4 -2
- package/dist/storage/desktop-native.js +90 -1
- package/dist/storage/fs.d.ts +17 -0
- package/dist/storage/index.d.ts +1 -0
- package/dist/storage/index.js +1 -0
- package/dist/storage/memory-vault-adapter.d.ts +3 -1
- package/dist/storage/memory-vault-adapter.js +60 -0
- package/dist/storage/remote-app-database.d.ts +19 -0
- package/dist/storage/remote-app-database.js +130 -0
- package/dist/storage/task-projection.d.ts +2 -1
- package/dist/storage/task-projection.js +7 -2
- package/dist/storage/turso-app-database.d.ts +3 -1
- package/dist/storage/turso-app-database.js +45 -0
- package/dist/storage/vault-session.js +11 -0
- package/dist/storage/vault-state.d.ts +1 -1
- package/dist/storage/vault.svelte.d.ts +3 -1
- package/dist/storage/vault.svelte.js +76 -3
- package/dist/sync-host-security.d.ts +285 -0
- package/dist/sync-host-security.js +2237 -0
- package/dist/sync-host.d.ts +179 -0
- package/dist/sync-host.js +769 -0
- package/dist/workspace.svelte.d.ts +1 -1
- package/dist/workspace.svelte.js +1 -1
- package/package.json +48 -10
package/dist/storage/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export * from "./fs";
|
|
|
2
2
|
export * from "./memory-vault-adapter";
|
|
3
3
|
export * from "./blob-store";
|
|
4
4
|
export * from "./app-database";
|
|
5
|
+
export * from "./remote-app-database";
|
|
5
6
|
export * from "./task-projection";
|
|
6
7
|
export * from "./index-projection";
|
|
7
8
|
export * from "./turso-app-database";
|
package/dist/storage/index.js
CHANGED
|
@@ -2,6 +2,7 @@ export * from "./fs";
|
|
|
2
2
|
export * from "./memory-vault-adapter";
|
|
3
3
|
export * from "./blob-store";
|
|
4
4
|
export * from "./app-database";
|
|
5
|
+
export * from "./remote-app-database";
|
|
5
6
|
export * from "./task-projection";
|
|
6
7
|
export * from "./index-projection";
|
|
7
8
|
export * from "./turso-app-database";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DataWriteOptions, ListedFiles, Stat, VaultAdapter, VaultAdapterCapabilities, VaultIdentityAdapter } from "./fs";
|
|
1
|
+
import type { DataWriteOptions, AtomicDataWriteOptions, ListedFiles, Stat, VaultAdapter, VaultAdapterCapabilities, VaultIdentityAdapter, VaultReadHandle } from "./fs";
|
|
2
2
|
export type MemoryVaultClock = number | (() => number);
|
|
3
3
|
export interface MemoryVaultAdapterOptions {
|
|
4
4
|
name?: string;
|
|
@@ -24,6 +24,8 @@ export declare class MemoryVaultAdapter implements VaultAdapter, VaultIdentityAd
|
|
|
24
24
|
stat(path: string): Promise<Stat | null>;
|
|
25
25
|
read(path: string): Promise<string>;
|
|
26
26
|
readBinary(path: string): Promise<ArrayBuffer>;
|
|
27
|
+
openRead(path: string): Promise<VaultReadHandle>;
|
|
28
|
+
atomicWrite(path: string, source: ReadableStream<Uint8Array>, options?: AtomicDataWriteOptions): Promise<void>;
|
|
27
29
|
write(path: string, data: string, options?: DataWriteOptions): Promise<void>;
|
|
28
30
|
writeBinary(path: string, data: ArrayBuffer, options?: DataWriteOptions): Promise<void>;
|
|
29
31
|
append(path: string, data: string, options?: DataWriteOptions): Promise<void>;
|
|
@@ -94,6 +94,66 @@ export class MemoryVaultAdapter {
|
|
|
94
94
|
? toArrayBuffer(new TextEncoder().encode(value))
|
|
95
95
|
: value.slice(0);
|
|
96
96
|
}
|
|
97
|
+
async openRead(path) {
|
|
98
|
+
const normalized = this.#path(path);
|
|
99
|
+
const value = this.#files.get(normalized);
|
|
100
|
+
if (!value)
|
|
101
|
+
throw fsError("ENOENT", normalized);
|
|
102
|
+
const bytes = typeof value.data === "string"
|
|
103
|
+
? new TextEncoder().encode(value.data)
|
|
104
|
+
: new Uint8Array(value.data.slice(0));
|
|
105
|
+
return {
|
|
106
|
+
size: bytes.byteLength,
|
|
107
|
+
mtime: value.stat.mtime,
|
|
108
|
+
stream: ({ offset = 0, length, signal } = {}) => {
|
|
109
|
+
const start = Math.max(0, Math.min(bytes.byteLength, Math.floor(offset)));
|
|
110
|
+
const end = Math.min(bytes.byteLength, start + Math.max(0, Math.floor(length ?? bytes.byteLength - start)));
|
|
111
|
+
let cursor = start;
|
|
112
|
+
return new ReadableStream({
|
|
113
|
+
pull(controller) {
|
|
114
|
+
if (signal?.aborted) {
|
|
115
|
+
controller.error(signal.reason ?? new DOMException("Aborted", "AbortError"));
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
if (cursor >= end) {
|
|
119
|
+
controller.close();
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
const next = Math.min(end, cursor + 64 * 1024);
|
|
123
|
+
controller.enqueue(bytes.slice(cursor, next));
|
|
124
|
+
cursor = next;
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
async atomicWrite(path, source, options = {}) {
|
|
131
|
+
const reader = source.getReader();
|
|
132
|
+
const chunks = [];
|
|
133
|
+
let size = 0;
|
|
134
|
+
try {
|
|
135
|
+
while (true) {
|
|
136
|
+
if (options.signal?.aborted) {
|
|
137
|
+
throw options.signal.reason ?? new DOMException("Aborted", "AbortError");
|
|
138
|
+
}
|
|
139
|
+
const next = await reader.read();
|
|
140
|
+
if (next.done)
|
|
141
|
+
break;
|
|
142
|
+
chunks.push(next.value);
|
|
143
|
+
size += next.value.byteLength;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
finally {
|
|
147
|
+
reader.releaseLock();
|
|
148
|
+
}
|
|
149
|
+
const bytes = new Uint8Array(size);
|
|
150
|
+
let offset = 0;
|
|
151
|
+
for (const chunk of chunks) {
|
|
152
|
+
bytes.set(chunk, offset);
|
|
153
|
+
offset += chunk.byteLength;
|
|
154
|
+
}
|
|
155
|
+
await this.writeBinary(path, bytes.buffer, options);
|
|
156
|
+
}
|
|
97
157
|
async write(path, data, options) {
|
|
98
158
|
await this.#writeValue(path, data, options);
|
|
99
159
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { AppDatabase } from "./app-database";
|
|
3
|
+
export declare const REMOTE_APP_DATABASE_MAX_ARGUMENTS = 4;
|
|
4
|
+
export declare const REMOTE_APP_DATABASE_MAX_MESSAGE_BYTES: number;
|
|
5
|
+
export declare const REMOTE_APP_DATABASE_METHODS: readonly ["migrate", "beginSearchIndexingBatch", "endSearchIndexingBatch", "configureSearchEmbeddingProvider", "getSearchEmbeddingProvider", "getSearchEmbeddingRuntimeStatus", "getSearchIndexStats", "getMeta", "setMeta", "scanMeta", "transactMeta", "getNotebookState", "setNotebookState", "deleteNotebookState", "loadMetadataSnapshot", "saveMetadataSnapshot", "getFileHistory", "storeFileHistoryRevision", "listNotifications", "upsertNotification", "markNotificationRead", "clearNotification", "clearAllNotifications", "getMemorySourceState", "listMemorySourceStates", "upsertMemorySourceState", "deleteMemorySourceState", "upsertMemoryCandidate", "queryMemoryCandidates", "deleteMemoryCandidatesByConversation", "recordMemoryRecallSignal", "listMemoryRecallSignals", "claimMemoryJob", "updateMemoryJob", "listMemoryJobs", "clearMemoryDerivedState", "getChangeRevision", "upsertIndexedFile", "getIndexedFile", "listIndexedFileManifest", "queryIndexedMetadata", "queryIndexedMetadataPage", "queryMetadataFacets", "queryMetadataLinks", "deleteIndexedFile", "renameIndexedFile", "upsertSearchDocument", "deleteSearchDocument", "getSearchDocument", "listSearchDocumentManifest", "listSearchDocuments", "rebuildSearchIndex", "searchDocuments", "searchDocumentPaths", "upsertTaskProjection", "deleteTaskProjection", "queryTasks", "getTaskRow", "listChildLinks", "listTaskDescendants", "registerProjectionDefinition", "unregisterProjectionDefinition", "replaceProjectionSource", "markProjectionSourceError", "deleteProjectionSource", "queryProjection", "getProjectionRow", "queryRelated"];
|
|
6
|
+
export type RemoteAppDatabaseMethod = (typeof REMOTE_APP_DATABASE_METHODS)[number];
|
|
7
|
+
export type RemoteAppDatabaseArgs<Method extends RemoteAppDatabaseMethod> = AppDatabase[Method] extends (...args: infer Args) => unknown ? Args : never;
|
|
8
|
+
export type RemoteAppDatabaseResult<Method extends RemoteAppDatabaseMethod> = AppDatabase[Method] extends (...args: never[]) => infer Result ? Awaited<Result> : never;
|
|
9
|
+
export type RemoteAppDatabaseDomain = "lifecycle" | "metadata" | "search" | "history" | "notifications" | "memory" | "tasks" | "projections";
|
|
10
|
+
export interface RemoteAppDatabaseContractEntry<Method extends RemoteAppDatabaseMethod> {
|
|
11
|
+
readonly method: Method;
|
|
12
|
+
readonly domain: RemoteAppDatabaseDomain;
|
|
13
|
+
readonly input: z.ZodType<RemoteAppDatabaseArgs<Method>>;
|
|
14
|
+
readonly output: z.ZodType<RemoteAppDatabaseResult<Method>>;
|
|
15
|
+
}
|
|
16
|
+
export declare const REMOTE_APP_DATABASE_CONTRACT: { readonly [Method in RemoteAppDatabaseMethod]: RemoteAppDatabaseContractEntry<Method>; };
|
|
17
|
+
export declare function isRemoteAppDatabaseMethod(value: unknown): value is RemoteAppDatabaseMethod;
|
|
18
|
+
export declare function parseRemoteAppDatabaseArgs<Method extends RemoteAppDatabaseMethod>(method: Method, value: unknown): RemoteAppDatabaseArgs<Method>;
|
|
19
|
+
export declare function parseRemoteAppDatabaseResult<Method extends RemoteAppDatabaseMethod>(method: Method, value: unknown): RemoteAppDatabaseResult<Method>;
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const REMOTE_APP_DATABASE_MAX_ARGUMENTS = 4;
|
|
3
|
+
export const REMOTE_APP_DATABASE_MAX_MESSAGE_BYTES = 32 * 1024 * 1024;
|
|
4
|
+
export const REMOTE_APP_DATABASE_METHODS = [
|
|
5
|
+
"migrate",
|
|
6
|
+
"beginSearchIndexingBatch",
|
|
7
|
+
"endSearchIndexingBatch",
|
|
8
|
+
"configureSearchEmbeddingProvider",
|
|
9
|
+
"getSearchEmbeddingProvider",
|
|
10
|
+
"getSearchEmbeddingRuntimeStatus",
|
|
11
|
+
"getSearchIndexStats",
|
|
12
|
+
"getMeta",
|
|
13
|
+
"setMeta",
|
|
14
|
+
"scanMeta",
|
|
15
|
+
"transactMeta",
|
|
16
|
+
"getNotebookState",
|
|
17
|
+
"setNotebookState",
|
|
18
|
+
"deleteNotebookState",
|
|
19
|
+
"loadMetadataSnapshot",
|
|
20
|
+
"saveMetadataSnapshot",
|
|
21
|
+
"getFileHistory",
|
|
22
|
+
"storeFileHistoryRevision",
|
|
23
|
+
"listNotifications",
|
|
24
|
+
"upsertNotification",
|
|
25
|
+
"markNotificationRead",
|
|
26
|
+
"clearNotification",
|
|
27
|
+
"clearAllNotifications",
|
|
28
|
+
"getMemorySourceState",
|
|
29
|
+
"listMemorySourceStates",
|
|
30
|
+
"upsertMemorySourceState",
|
|
31
|
+
"deleteMemorySourceState",
|
|
32
|
+
"upsertMemoryCandidate",
|
|
33
|
+
"queryMemoryCandidates",
|
|
34
|
+
"deleteMemoryCandidatesByConversation",
|
|
35
|
+
"recordMemoryRecallSignal",
|
|
36
|
+
"listMemoryRecallSignals",
|
|
37
|
+
"claimMemoryJob",
|
|
38
|
+
"updateMemoryJob",
|
|
39
|
+
"listMemoryJobs",
|
|
40
|
+
"clearMemoryDerivedState",
|
|
41
|
+
"getChangeRevision",
|
|
42
|
+
"upsertIndexedFile",
|
|
43
|
+
"getIndexedFile",
|
|
44
|
+
"listIndexedFileManifest",
|
|
45
|
+
"queryIndexedMetadata",
|
|
46
|
+
"queryIndexedMetadataPage",
|
|
47
|
+
"queryMetadataFacets",
|
|
48
|
+
"queryMetadataLinks",
|
|
49
|
+
"deleteIndexedFile",
|
|
50
|
+
"renameIndexedFile",
|
|
51
|
+
"upsertSearchDocument",
|
|
52
|
+
"deleteSearchDocument",
|
|
53
|
+
"getSearchDocument",
|
|
54
|
+
"listSearchDocumentManifest",
|
|
55
|
+
"listSearchDocuments",
|
|
56
|
+
"rebuildSearchIndex",
|
|
57
|
+
"searchDocuments",
|
|
58
|
+
"searchDocumentPaths",
|
|
59
|
+
"upsertTaskProjection",
|
|
60
|
+
"deleteTaskProjection",
|
|
61
|
+
"queryTasks",
|
|
62
|
+
"getTaskRow",
|
|
63
|
+
"listChildLinks",
|
|
64
|
+
"listTaskDescendants",
|
|
65
|
+
"registerProjectionDefinition",
|
|
66
|
+
"unregisterProjectionDefinition",
|
|
67
|
+
"replaceProjectionSource",
|
|
68
|
+
"markProjectionSourceError",
|
|
69
|
+
"deleteProjectionSource",
|
|
70
|
+
"queryProjection",
|
|
71
|
+
"getProjectionRow",
|
|
72
|
+
"queryRelated",
|
|
73
|
+
];
|
|
74
|
+
const remoteMethodSet = new Set(REMOTE_APP_DATABASE_METHODS);
|
|
75
|
+
function jsonBytes(value) {
|
|
76
|
+
const json = JSON.stringify(value);
|
|
77
|
+
return typeof json === "string"
|
|
78
|
+
? new TextEncoder().encode(json).byteLength
|
|
79
|
+
: 0;
|
|
80
|
+
}
|
|
81
|
+
function isBoundedJson(value) {
|
|
82
|
+
try {
|
|
83
|
+
return jsonBytes(value) <= REMOTE_APP_DATABASE_MAX_MESSAGE_BYTES;
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function methodDomain(method) {
|
|
90
|
+
if (/memory/iu.test(method))
|
|
91
|
+
return "memory";
|
|
92
|
+
if (/notification/iu.test(method))
|
|
93
|
+
return "notifications";
|
|
94
|
+
if (/history/iu.test(method))
|
|
95
|
+
return "history";
|
|
96
|
+
if (/task|childLinks/iu.test(method))
|
|
97
|
+
return "tasks";
|
|
98
|
+
if (/projection|related/iu.test(method))
|
|
99
|
+
return "projections";
|
|
100
|
+
if (/search/iu.test(method))
|
|
101
|
+
return "search";
|
|
102
|
+
if (method === "migrate" ||
|
|
103
|
+
method === "beginSearchIndexingBatch" ||
|
|
104
|
+
method === "endSearchIndexingBatch" ||
|
|
105
|
+
method === "getChangeRevision" ||
|
|
106
|
+
method === "clearMemoryDerivedState") {
|
|
107
|
+
return "lifecycle";
|
|
108
|
+
}
|
|
109
|
+
return "metadata";
|
|
110
|
+
}
|
|
111
|
+
function contractEntry(method) {
|
|
112
|
+
return {
|
|
113
|
+
method,
|
|
114
|
+
domain: methodDomain(method),
|
|
115
|
+
input: z.custom((value) => Array.isArray(value) &&
|
|
116
|
+
value.length <= REMOTE_APP_DATABASE_MAX_ARGUMENTS &&
|
|
117
|
+
isBoundedJson(value), "Invalid or oversized AppDatabase arguments"),
|
|
118
|
+
output: z.custom((value) => value === undefined || isBoundedJson(value), "Invalid or oversized AppDatabase result"),
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
export const REMOTE_APP_DATABASE_CONTRACT = Object.fromEntries(REMOTE_APP_DATABASE_METHODS.map((method) => [method, contractEntry(method)]));
|
|
122
|
+
export function isRemoteAppDatabaseMethod(value) {
|
|
123
|
+
return typeof value === "string" && remoteMethodSet.has(value);
|
|
124
|
+
}
|
|
125
|
+
export function parseRemoteAppDatabaseArgs(method, value) {
|
|
126
|
+
return REMOTE_APP_DATABASE_CONTRACT[method].input.parse(value);
|
|
127
|
+
}
|
|
128
|
+
export function parseRemoteAppDatabaseResult(method, value) {
|
|
129
|
+
return REMOTE_APP_DATABASE_CONTRACT[method].output.parse(value);
|
|
130
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PUBLIC_TASKS_PROJECTION_ID, PUBLIC_TASK_OCCURRENCES_PROJECTION_ID, type IndexFieldDefinition, type IndexQuery } from "./index-projection";
|
|
2
|
-
export declare const TASK_PROJECTION_VERSION =
|
|
2
|
+
export declare const TASK_PROJECTION_VERSION = 4;
|
|
3
3
|
export declare const TASK_OCCURRENCE_PROJECTION_VERSION = 1;
|
|
4
4
|
export { PUBLIC_TASKS_PROJECTION_ID, PUBLIC_TASK_OCCURRENCES_PROJECTION_ID };
|
|
5
5
|
export declare const TASK_PROJECTION_FIELDS: Record<string, IndexFieldDefinition>;
|
|
@@ -91,6 +91,7 @@ export interface AppDatabaseTaskRecord {
|
|
|
91
91
|
kind: AppDatabaseTaskKind;
|
|
92
92
|
title: string;
|
|
93
93
|
status: AppDatabaseTaskStatus;
|
|
94
|
+
priority?: "low" | "medium" | "high" | null;
|
|
94
95
|
inbox: boolean;
|
|
95
96
|
startKind: AppDatabaseTaskStartKind;
|
|
96
97
|
startDate?: string | null;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PUBLIC_TASKS_PROJECTION_ID, PUBLIC_TASK_OCCURRENCES_PROJECTION_ID, and, eq, gt, isNull, lt, lte, or, } from "./index-projection";
|
|
2
|
-
export const TASK_PROJECTION_VERSION =
|
|
2
|
+
export const TASK_PROJECTION_VERSION = 4;
|
|
3
3
|
export const TASK_OCCURRENCE_PROJECTION_VERSION = 1;
|
|
4
4
|
export { PUBLIC_TASKS_PROJECTION_ID, PUBLIC_TASK_OCCURRENCES_PROJECTION_ID };
|
|
5
5
|
export const TASK_PROJECTION_FIELDS = {
|
|
@@ -8,6 +8,7 @@ export const TASK_PROJECTION_FIELDS = {
|
|
|
8
8
|
kind: { type: "string", indexed: true },
|
|
9
9
|
title: { type: "string", indexed: true, sortable: true },
|
|
10
10
|
status: { type: "string", indexed: true, sortable: true },
|
|
11
|
+
priority: { type: "string", indexed: true, sortable: true },
|
|
11
12
|
inbox: { type: "boolean", indexed: true },
|
|
12
13
|
startKind: { type: "string", indexed: true },
|
|
13
14
|
startDate: { type: "date", indexed: true, sortable: true },
|
|
@@ -148,7 +149,11 @@ export function taskQueryToIndexQuery(query = {}) {
|
|
|
148
149
|
}
|
|
149
150
|
}
|
|
150
151
|
return {
|
|
151
|
-
where: clauses.length === 1
|
|
152
|
+
where: clauses.length === 1
|
|
153
|
+
? clauses[0]
|
|
154
|
+
: clauses.length
|
|
155
|
+
? and(...clauses)
|
|
156
|
+
: undefined,
|
|
152
157
|
limit: query.limit,
|
|
153
158
|
};
|
|
154
159
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AppDatabase, type AppDatabaseChangeListener, type AppDatabaseDescriptor, type AppDatabaseFileHistory, type AppDatabaseIndexedFile, type AppDatabaseIndexedFileManifestPage, type AppDatabaseIndexedFileManifestQuery, type AppDatabaseIndexedMetadataPage, type AppDatabaseIndexedMetadataPageQuery, type AppDatabaseIndexedMetadataQuery, type AppDatabaseIndexedMetadataRow, type AppDatabaseKind, type AppDatabaseLinkRecord, type AppDatabaseMetadataFacetQuery, type AppDatabaseMetadataFacetRow, type AppDatabaseMetadataLinkQuery, type AppDatabaseMemoryCandidateInput, type AppDatabaseMemoryCandidateQuery, type AppDatabaseMemoryCandidateResult, type AppDatabaseMemoryJobClaimInput, type AppDatabaseMemoryJobRecord, type AppDatabaseMemoryJobUpdateInput, type AppDatabaseMemoryRecallSignalRecord, type AppDatabaseMemorySourceRecord, type AppDatabaseNotebookState, type AppDatabaseNotificationRecord, type AppDatabaseOpenContext, type AppDatabaseProvider, type AppDatabaseSearchIndexStats, type AppDatabaseSearchOptions, type AppDatabaseSearchResult, type AppDatabaseStoreFileHistoryRevisionInput, type AppDatabaseStoreFileHistoryRevisionResult, type MetadataCacheSnapshot, type SearchDocumentRecord, type SearchDocumentManifestPage, type SearchDocumentManifestQuery, type SearchEmbeddingProviderConfig } from "./app-database";
|
|
1
|
+
import { type AppDatabase, type AppDatabaseChangeListener, type AppDatabaseDescriptor, type AppDatabaseFileHistory, type AppDatabaseIndexedFile, type AppDatabaseIndexedFileManifestPage, type AppDatabaseIndexedFileManifestQuery, type AppDatabaseIndexedMetadataPage, type AppDatabaseIndexedMetadataPageQuery, type AppDatabaseIndexedMetadataQuery, type AppDatabaseIndexedMetadataRow, type AppDatabaseKind, type AppDatabaseLinkRecord, type AppDatabaseMetadataFacetQuery, type AppDatabaseMetadataFacetRow, type AppDatabaseMetadataLinkQuery, type AppDatabaseMemoryCandidateInput, type AppDatabaseMemoryCandidateQuery, type AppDatabaseMemoryCandidateResult, type AppDatabaseMemoryJobClaimInput, type AppDatabaseMemoryJobRecord, type AppDatabaseMemoryJobUpdateInput, type AppDatabaseMemoryRecallSignalRecord, type AppDatabaseMemorySourceRecord, type AppDatabaseMetaScanPage, type AppDatabaseMetaScanQuery, type AppDatabaseMetaTransaction, type AppDatabaseMetaTransactionResult, type AppDatabaseNotebookState, type AppDatabaseNotificationRecord, type AppDatabaseOpenContext, type AppDatabaseProvider, type AppDatabaseSearchIndexStats, type AppDatabaseSearchOptions, type AppDatabaseSearchResult, type AppDatabaseStoreFileHistoryRevisionInput, type AppDatabaseStoreFileHistoryRevisionResult, type MetadataCacheSnapshot, type SearchDocumentRecord, type SearchDocumentManifestPage, type SearchDocumentManifestQuery, type SearchEmbeddingProviderConfig } from "./app-database";
|
|
2
2
|
import { type IndexProjectionDefinitionRecord, type IndexQuery, type IndexQueryResult, type IndexRelatedQuery, type MarkProjectionSourceErrorInput, type ReplaceProjectionSourceInput } from "./index-projection";
|
|
3
3
|
import type { AppDatabaseTaskChildQuery, AppDatabaseTaskQuery, AppDatabaseTaskRecord } from "./task-projection";
|
|
4
4
|
import { type SearchEmbeddingRuntimeStatus } from "./search-embedding-provider";
|
|
@@ -52,6 +52,8 @@ export declare class TursoAppDatabase implements AppDatabase {
|
|
|
52
52
|
getSearchIndexStats(): Promise<AppDatabaseSearchIndexStats>;
|
|
53
53
|
getMeta<T = unknown>(key: string): Promise<T | undefined>;
|
|
54
54
|
setMeta(key: string, value: unknown): Promise<void>;
|
|
55
|
+
scanMeta<T = unknown>({ prefix, after, limit, }: AppDatabaseMetaScanQuery): Promise<AppDatabaseMetaScanPage<T>>;
|
|
56
|
+
transactMeta({ checks, mutations, }: AppDatabaseMetaTransaction): Promise<AppDatabaseMetaTransactionResult>;
|
|
55
57
|
getNotebookState(sourcePath: string): Promise<AppDatabaseNotebookState | undefined>;
|
|
56
58
|
setNotebookState(sourcePath: string, state: AppDatabaseNotebookState): Promise<void>;
|
|
57
59
|
deleteNotebookState(sourcePath: string): Promise<void>;
|
|
@@ -735,6 +735,10 @@ export class TursoAppDatabase {
|
|
|
735
735
|
: undefined;
|
|
736
736
|
}
|
|
737
737
|
async setMeta(key, value) {
|
|
738
|
+
if (value === undefined) {
|
|
739
|
+
await this.commit([{ sql: "DELETE FROM app_meta WHERE key = ?", args: [key] }], ["meta"]);
|
|
740
|
+
return;
|
|
741
|
+
}
|
|
738
742
|
await this.commit([
|
|
739
743
|
{
|
|
740
744
|
sql: `INSERT INTO app_meta (key, value_json) VALUES (?, ?)
|
|
@@ -743,6 +747,47 @@ export class TursoAppDatabase {
|
|
|
743
747
|
},
|
|
744
748
|
], ["meta"]);
|
|
745
749
|
}
|
|
750
|
+
async scanMeta({ prefix, after, limit = 100, }) {
|
|
751
|
+
const boundedLimit = Math.max(1, Math.min(500, Math.floor(limit)));
|
|
752
|
+
const rows = await this.requireConnection().all(`SELECT key, value_json FROM app_meta
|
|
753
|
+
WHERE substr(key, 1, ?) = ? AND key > ?
|
|
754
|
+
ORDER BY key ASC LIMIT ?`, prefix.length, prefix, after ?? prefix, boundedLimit + 1);
|
|
755
|
+
const pageRows = rows.slice(0, boundedLimit);
|
|
756
|
+
return {
|
|
757
|
+
entries: pageRows.map((row) => ({
|
|
758
|
+
key: row.key,
|
|
759
|
+
value: parseJson(row.value_json, undefined),
|
|
760
|
+
})),
|
|
761
|
+
nextCursor: rows.length > pageRows.length ? pageRows.at(-1)?.key : undefined,
|
|
762
|
+
};
|
|
763
|
+
}
|
|
764
|
+
async transactMeta({ checks = [], mutations, }) {
|
|
765
|
+
const committed = this.commitQueue.then(async () => {
|
|
766
|
+
for (const check of checks) {
|
|
767
|
+
const row = await this.requireConnection().get("SELECT value_json FROM app_meta WHERE key = ?", check.key);
|
|
768
|
+
if (check.exists !== undefined && Boolean(row) !== check.exists) {
|
|
769
|
+
return { applied: false };
|
|
770
|
+
}
|
|
771
|
+
if ("value" in check &&
|
|
772
|
+
JSON.stringify(row ? parseJson(row.value_json, undefined) : undefined) !== JSON.stringify(check.value)) {
|
|
773
|
+
return { applied: false };
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
const statements = mutations.map((mutation) => mutation.delete || mutation.value === undefined
|
|
777
|
+
? { sql: "DELETE FROM app_meta WHERE key = ?", args: [mutation.key] }
|
|
778
|
+
: {
|
|
779
|
+
sql: `INSERT INTO app_meta (key, value_json) VALUES (?, ?)
|
|
780
|
+
ON CONFLICT(key) DO UPDATE SET value_json = excluded.value_json`,
|
|
781
|
+
args: [mutation.key, JSON.stringify(mutation.value)],
|
|
782
|
+
});
|
|
783
|
+
if (statements.length > 0) {
|
|
784
|
+
await this.commitImmediately(statements, ["meta"]);
|
|
785
|
+
}
|
|
786
|
+
return { applied: true };
|
|
787
|
+
});
|
|
788
|
+
this.commitQueue = committed.then(() => undefined, () => undefined);
|
|
789
|
+
return committed;
|
|
790
|
+
}
|
|
746
791
|
async getNotebookState(sourcePath) {
|
|
747
792
|
return this.getMeta(notebookStateMetaKey(sourcePath));
|
|
748
793
|
}
|
|
@@ -138,6 +138,17 @@ async function createPreferredAppDatabase(vaultId, runtime, provider) {
|
|
|
138
138
|
});
|
|
139
139
|
return { appDatabase: database, state: readyState(database, false) };
|
|
140
140
|
}
|
|
141
|
+
if (runtime === "deno-server") {
|
|
142
|
+
if (!provider) {
|
|
143
|
+
throw new Error("deno-server requires an AppDatabaseProvider");
|
|
144
|
+
}
|
|
145
|
+
const database = await provider.open({
|
|
146
|
+
vaultId,
|
|
147
|
+
runtime,
|
|
148
|
+
role: "direct",
|
|
149
|
+
});
|
|
150
|
+
return { appDatabase: database, state: readyState(database, false) };
|
|
151
|
+
}
|
|
141
152
|
if (runtime === "web-pwa") {
|
|
142
153
|
return createBrowserAppDatabase(vaultId, provider ?? new TursoWasmAppDatabaseProvider());
|
|
143
154
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { DataAdapter } from "./fs";
|
|
2
2
|
import { type UseStore } from "./keyval";
|
|
3
|
-
export type VaultStorageKind = "opfs" | "file-system-access" | "desktop-folder";
|
|
3
|
+
export type VaultStorageKind = "opfs" | "file-system-access" | "desktop-folder" | "server-hosted";
|
|
4
4
|
export type BootstrapAppearanceMode = "dark" | "light" | "system";
|
|
5
5
|
export interface VaultProfileDemoMetadata {
|
|
6
6
|
source: "e2e-vault";
|
|
@@ -103,7 +103,9 @@ export declare class Vault extends EventDispatcher<{
|
|
|
103
103
|
* children
|
|
104
104
|
* @public
|
|
105
105
|
*/
|
|
106
|
-
delete(file: TAbstractFile, force?: boolean
|
|
106
|
+
delete(file: TAbstractFile, force?: boolean, context?: {
|
|
107
|
+
operationOrigin?: string;
|
|
108
|
+
}): Promise<void>;
|
|
107
109
|
trash(file: TAbstractFile, system?: boolean): Promise<void>;
|
|
108
110
|
/**
|
|
109
111
|
* Read a plaintext file that is stored inside the vault, directly from disk.
|
|
@@ -260,7 +260,7 @@ export class Vault extends EventDispatcher {
|
|
|
260
260
|
* children
|
|
261
261
|
* @public
|
|
262
262
|
*/
|
|
263
|
-
delete(file, force) {
|
|
263
|
+
delete(file, force, context = {}) {
|
|
264
264
|
const remove = file instanceof TFolder
|
|
265
265
|
? this.adapter.rmdir(file.path, force ?? true)
|
|
266
266
|
: this.adapter.remove(file.path);
|
|
@@ -282,7 +282,7 @@ export class Vault extends EventDispatcher {
|
|
|
282
282
|
}
|
|
283
283
|
this.cache.invalidate(file.path);
|
|
284
284
|
this.dispatch("delete", file);
|
|
285
|
-
this.dispatch("all", "delete", file, { force });
|
|
285
|
+
this.dispatch("all", "delete", file, { force, ...context });
|
|
286
286
|
});
|
|
287
287
|
}
|
|
288
288
|
trash(file, system = true) {
|
|
@@ -334,6 +334,79 @@ export class Vault extends EventDispatcher {
|
|
|
334
334
|
readBinary(file) {
|
|
335
335
|
return this.adapter.readBinary(file.path);
|
|
336
336
|
}
|
|
337
|
+
/** Open a stable streamed snapshot of a file when the adapter supports it. */
|
|
338
|
+
async openRead(file) {
|
|
339
|
+
const adapter = this.adapter;
|
|
340
|
+
if (adapter.openRead)
|
|
341
|
+
return adapter.openRead(file.path);
|
|
342
|
+
const data = new Uint8Array(await adapter.readBinary(file.path));
|
|
343
|
+
return {
|
|
344
|
+
size: data.byteLength,
|
|
345
|
+
mtime: file.stat.mtime,
|
|
346
|
+
stream: ({ offset = 0, length, signal } = {}) => {
|
|
347
|
+
const start = Math.max(0, Math.min(data.byteLength, Math.floor(offset)));
|
|
348
|
+
const end = Math.min(data.byteLength, start + Math.max(0, Math.floor(length ?? data.byteLength - start)));
|
|
349
|
+
return new ReadableStream({
|
|
350
|
+
start(controller) {
|
|
351
|
+
if (signal?.aborted) {
|
|
352
|
+
controller.error(signal.reason ?? new DOMException("Aborted", "AbortError"));
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
controller.enqueue(data.slice(start, end));
|
|
356
|
+
controller.close();
|
|
357
|
+
},
|
|
358
|
+
});
|
|
359
|
+
},
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
/** Stream a file into the adapter's atomic or strongest safe replacement path. */
|
|
363
|
+
async atomicWrite(path, source, options = {}) {
|
|
364
|
+
path = this.getPath(path);
|
|
365
|
+
const existed = this.getFileByPath(path);
|
|
366
|
+
const adapter = this.adapter;
|
|
367
|
+
if (adapter.atomicWrite) {
|
|
368
|
+
await adapter.atomicWrite(path, source, options);
|
|
369
|
+
}
|
|
370
|
+
else {
|
|
371
|
+
const reader = source.getReader();
|
|
372
|
+
const chunks = [];
|
|
373
|
+
let size = 0;
|
|
374
|
+
try {
|
|
375
|
+
while (true) {
|
|
376
|
+
if (options.signal?.aborted) {
|
|
377
|
+
throw options.signal.reason ?? new DOMException("Aborted", "AbortError");
|
|
378
|
+
}
|
|
379
|
+
const next = await reader.read();
|
|
380
|
+
if (next.done)
|
|
381
|
+
break;
|
|
382
|
+
chunks.push(next.value);
|
|
383
|
+
size += next.value.byteLength;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
finally {
|
|
387
|
+
reader.releaseLock();
|
|
388
|
+
}
|
|
389
|
+
const data = new Uint8Array(size);
|
|
390
|
+
let offset = 0;
|
|
391
|
+
for (const chunk of chunks) {
|
|
392
|
+
data.set(chunk, offset);
|
|
393
|
+
offset += chunk.byteLength;
|
|
394
|
+
}
|
|
395
|
+
await adapter.writeBinary(path, data.buffer, options);
|
|
396
|
+
}
|
|
397
|
+
this.files = await this.loadPath("/", {});
|
|
398
|
+
this.rebuildFileNameIndex();
|
|
399
|
+
const file = this.getFileByPath(path);
|
|
400
|
+
if (!file)
|
|
401
|
+
throw new Error(`Unable to write file: ${path}`);
|
|
402
|
+
this.cache.invalidate(path);
|
|
403
|
+
const event = existed ? "modify" : "create";
|
|
404
|
+
this.dispatch(event, file);
|
|
405
|
+
this.dispatch("all", event, file, {
|
|
406
|
+
operationOrigin: options.operationOrigin,
|
|
407
|
+
});
|
|
408
|
+
return file;
|
|
409
|
+
}
|
|
337
410
|
/**
|
|
338
411
|
* Rename or move a file. To ensure links are automatically renamed, use
|
|
339
412
|
* {@link FileManager.renameFile} instead.
|
|
@@ -364,7 +437,7 @@ export class Vault extends EventDispatcher {
|
|
|
364
437
|
if (newFile) {
|
|
365
438
|
this.cache.rename(file.path, newFile.path);
|
|
366
439
|
this.dispatch("rename", newFile, oldPath);
|
|
367
|
-
this.dispatch("all", "rename",
|
|
440
|
+
this.dispatch("all", "rename", newFile, { oldPath });
|
|
368
441
|
}
|
|
369
442
|
else {
|
|
370
443
|
console.warn(`Failed to rename file: ${file.path}`);
|