@peers-app/peers-sdk 0.29.2 → 0.30.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/contracts/contract-resolvers.js +1 -0
- package/dist/contracts/index.d.ts +1 -0
- package/dist/contracts/index.js +1 -0
- package/dist/contracts/system/file-storage-contract.d.ts +76 -0
- package/dist/contracts/system/file-storage-contract.js +75 -0
- package/dist/contracts/system/files-contract.d.ts +5 -1
- package/dist/contracts/system/files-contract.js +50 -9
- package/dist/contracts/system/files-shared.d.ts +68 -3
- package/dist/contracts/system/files-shared.js +65 -5
- package/dist/contracts/validate.d.ts +1 -0
- package/dist/contracts/validate.js +6 -1
- package/dist/data/derived-row-id.d.ts +26 -0
- package/dist/data/derived-row-id.js +47 -0
- package/dist/data/files/chunk-store.d.ts +112 -0
- package/dist/data/files/chunk-store.js +107 -0
- package/dist/data/files/file-read-stream.d.ts +32 -3
- package/dist/data/files/file-read-stream.js +44 -29
- package/dist/data/files/file-rows.d.ts +68 -0
- package/dist/data/files/file-rows.js +158 -0
- package/dist/data/files/file-write-stream.d.ts +26 -0
- package/dist/data/files/file-write-stream.js +66 -42
- package/dist/data/files/file.types.d.ts +44 -23
- package/dist/data/files/file.types.js +33 -51
- package/dist/data/files/files.d.ts +27 -24
- package/dist/data/files/files.js +63 -85
- package/dist/data/files/index.d.ts +2 -0
- package/dist/data/files/index.js +2 -0
- package/dist/data/index.d.ts +1 -0
- package/dist/data/index.js +1 -0
- package/dist/data/messages.d.ts +21 -0
- package/dist/data/messages.js +21 -1
- package/dist/data/orm/sql.data-source.d.ts +2 -1
- package/dist/data/orm/sql.data-source.js +1 -0
- package/dist/data/orm/types.js +12 -0
- package/dist/data/package-versions.js +3 -3
- package/dist/define/index.d.ts +1 -1
- package/dist/define/index.js +2 -1
- package/dist/define/system-contracts.d.ts +9 -2
- package/dist/define/system-contracts.js +6 -2
- package/dist/device-pairing/types.d.ts +2 -2
- package/dist/package-build/build-package.d.ts +12 -0
- package/dist/package-build/build-package.js +45 -6
- package/dist/package-build/cli.js +8 -0
- package/dist/package-build/contract-source.js +7 -5
- package/dist/package-installer/package-installer.d.ts +3 -5
- package/dist/package-installer/package-installer.js +5 -21
- package/dist/package-installer/package-propagation.js +6 -17
- package/dist/system-ids.d.ts +2 -0
- package/dist/system-ids.js +3 -1
- package/dist/types/field-type.d.ts +14 -0
- package/dist/types/field-type.js +14 -1
- package/dist/types/zod-types.d.ts +10 -0
- package/dist/types/zod-types.js +25 -7
- package/package.json +1 -1
package/dist/data/files/files.js
CHANGED
|
@@ -4,16 +4,19 @@ exports.FilesTable = void 0;
|
|
|
4
4
|
exports.Files = Files;
|
|
5
5
|
const user_context_singleton_1 = require("../../context/user-context-singleton");
|
|
6
6
|
const rpc_types_1 = require("../../rpc-types");
|
|
7
|
-
const utils_1 = require("../../utils");
|
|
8
7
|
const orm_1 = require("../orm");
|
|
9
8
|
const table_definitions_system_1 = require("../orm/table-definitions.system");
|
|
9
|
+
const chunk_store_1 = require("./chunk-store");
|
|
10
10
|
const file_types_1 = require("./file.types");
|
|
11
11
|
const file_read_stream_1 = require("./file-read-stream");
|
|
12
|
+
const file_rows_1 = require("./file-rows");
|
|
12
13
|
const file_write_stream_1 = require("./file-write-stream");
|
|
13
14
|
/**
|
|
14
15
|
* The chunked, content-hashed file store of one data context. Rows describe files; the bytes
|
|
15
|
-
* live in chunks
|
|
16
|
-
* device when it reads.
|
|
16
|
+
* live in chunks in the account's chunk store, shared by hash, and a device fetches a missing
|
|
17
|
+
* chunk from a connected device when it reads. A file's id is derived from its content, and its row never changes.
|
|
18
|
+
* Write through {@link FilesTable.saveFile}, never the table methods. The rules are checked here
|
|
19
|
+
* in every context, and by every device on the rows it receives in a group (`file-rows.ts`).
|
|
17
20
|
*/
|
|
18
21
|
class FilesTable extends orm_1.Table {
|
|
19
22
|
/** @deprecated Direct inserts forbidden; use saveFile() or saveFileRecord() */
|
|
@@ -35,19 +38,31 @@ class FilesTable extends orm_1.Table {
|
|
|
35
38
|
/**
|
|
36
39
|
* Start writing a file in chunks; `finalize()` saves its row.
|
|
37
40
|
*
|
|
38
|
-
* @param metadata - The new file's
|
|
41
|
+
* @param metadata - The new file's name, MIME type and `keep`.
|
|
39
42
|
*/
|
|
40
43
|
async createWriteStream(metadata) {
|
|
41
44
|
return new file_write_stream_1.FileWriteStream(metadata, this);
|
|
42
45
|
}
|
|
43
46
|
/**
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
47
|
+
* Store a file's row as it is, after the checks every device makes: a new row must have the
|
|
48
|
+
* id derived from its content (or be a legacy row), and a stored row never changes. Storing
|
|
49
|
+
* the same file again writes nothing. Writers use {@link saveFile} or a write stream; this is
|
|
50
|
+
* for copying a row from another context with its id.
|
|
51
|
+
*
|
|
52
|
+
* @param fileRecord - The row.
|
|
53
|
+
* @returns The row as stored.
|
|
54
|
+
* @throws When the row is refused, or a different row has its id.
|
|
48
55
|
*/
|
|
49
56
|
async saveFileRecord(fileRecord) {
|
|
50
|
-
|
|
57
|
+
const existing = await super.get(fileRecord.fileId);
|
|
58
|
+
(0, file_rows_1.checkFileWrite)(existing, fileRecord, fileRecord.fileId);
|
|
59
|
+
if (existing)
|
|
60
|
+
return existing;
|
|
61
|
+
// Another save or sync apply may have inserted the row since the read. In particular, the
|
|
62
|
+
// personal context has no data-source write check, so never let this become an update.
|
|
63
|
+
const saved = await super.save(fileRecord, { insertOnly: true });
|
|
64
|
+
(0, file_rows_1.checkFileWrite)(saved, fileRecord, fileRecord.fileId);
|
|
65
|
+
return saved;
|
|
51
66
|
}
|
|
52
67
|
/**
|
|
53
68
|
* Open a file for chunked reads.
|
|
@@ -62,27 +77,19 @@ class FilesTable extends orm_1.Table {
|
|
|
62
77
|
if (!fileRecord) {
|
|
63
78
|
return null;
|
|
64
79
|
}
|
|
65
|
-
return new file_read_stream_1.FileReadStream(fileRecord,
|
|
80
|
+
return new file_read_stream_1.FileReadStream(fileRecord, preloadChunksCount, skipVerification);
|
|
66
81
|
}
|
|
67
82
|
/**
|
|
68
|
-
* Save a whole file: chunk it, store the chunks and write its row.
|
|
83
|
+
* Save a whole file: chunk it, store the chunks and write its row. The same bytes, name, MIME
|
|
84
|
+
* type and `keep` give the same file, whose chunks are stored again.
|
|
69
85
|
*
|
|
70
|
-
* @param metaData - The file's
|
|
86
|
+
* @param metaData - The file's name, MIME type and `keep` (true unless given).
|
|
71
87
|
* @param data - The bytes, or a string saved as UTF-8.
|
|
72
|
-
* @returns The
|
|
88
|
+
* @returns The file's row.
|
|
73
89
|
*/
|
|
74
90
|
async saveFile(metaData, data) {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
...metaData,
|
|
78
|
-
fileSize: data.length, // Set the actual file size
|
|
79
|
-
});
|
|
80
|
-
// Write the entire data to the stream
|
|
81
|
-
if (typeof data === "string") {
|
|
82
|
-
data = new Uint8Array(Buffer.from(data, "utf8"));
|
|
83
|
-
}
|
|
84
|
-
await writeStream.write(data);
|
|
85
|
-
// Finalize and return the result
|
|
91
|
+
const writeStream = await this.createWriteStream(metaData);
|
|
92
|
+
await writeStream.write(typeof data === "string" ? new Uint8Array(Buffer.from(data, "utf8")) : data);
|
|
86
93
|
return await writeStream.finalize();
|
|
87
94
|
}
|
|
88
95
|
/**
|
|
@@ -93,8 +100,7 @@ class FilesTable extends orm_1.Table {
|
|
|
93
100
|
* @returns The bytes, or null when no such file row exists.
|
|
94
101
|
*/
|
|
95
102
|
async getFileContents(fileId, opts) {
|
|
96
|
-
|
|
97
|
-
const readStream = await this.openReadStream(fileId, undefined, opts?.skipVerification);
|
|
103
|
+
const readStream = await this.openReadStream(fileId, file_types_1.FILE_FETCH_WINDOW, opts?.skipVerification);
|
|
98
104
|
if (!readStream) {
|
|
99
105
|
return null;
|
|
100
106
|
}
|
|
@@ -102,65 +108,43 @@ class FilesTable extends orm_1.Table {
|
|
|
102
108
|
return await readStream.readAll();
|
|
103
109
|
}
|
|
104
110
|
/**
|
|
105
|
-
*
|
|
111
|
+
* Make sure this device has every chunk of a file, fetching the missing ones from connected
|
|
112
|
+
* devices {@link FILE_FETCH_WINDOW} at a time, without reading the file into memory.
|
|
106
113
|
*
|
|
107
|
-
* @param fileId - File to
|
|
114
|
+
* @param fileId - File to fetch.
|
|
115
|
+
* @returns Whether every chunk is now on this device; false for a file with no row.
|
|
108
116
|
*/
|
|
109
|
-
async
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
117
|
+
async fetchFile(fileId) {
|
|
118
|
+
const file = await this.get(fileId);
|
|
119
|
+
if (!file)
|
|
120
|
+
return false;
|
|
121
|
+
const store = await (0, chunk_store_1.getChunkStore)();
|
|
122
|
+
const chunkHashes = file.chunkHashes ?? [];
|
|
123
|
+
let complete = chunkHashes.length > 0 || file.fileSize === 0;
|
|
124
|
+
for (let start = 0; start < chunkHashes.length; start += file_types_1.FILE_FETCH_WINDOW) {
|
|
125
|
+
const window = chunkHashes.slice(start, start + file_types_1.FILE_FETCH_WINDOW);
|
|
126
|
+
const fetched = await Promise.all(window.map(async (hash) => (await store.has(hash)) ||
|
|
127
|
+
// The downloader checks a downloaded chunk's hash and stores it.
|
|
128
|
+
(await (0, chunk_store_1.downloadChunk)(hash).catch(() => null)) !== null));
|
|
129
|
+
if (fetched.includes(false))
|
|
130
|
+
complete = false;
|
|
118
131
|
}
|
|
119
|
-
|
|
120
|
-
// TODO Chunk cleanup needs to be implemented as a separate garbage collection process
|
|
121
|
-
// that removes chunks not referenced by any files
|
|
122
|
-
// Delete file record from database
|
|
123
|
-
await super.delete(fileId);
|
|
132
|
+
return complete;
|
|
124
133
|
}
|
|
125
134
|
/**
|
|
126
|
-
*
|
|
135
|
+
* Delete a legacy bundle row, which the runtime owns. Every other file is permanent: it's
|
|
136
|
+
* collected once nothing references it. Chunks stay stored, since other files may share them.
|
|
127
137
|
*
|
|
128
|
-
* @param
|
|
129
|
-
* @
|
|
130
|
-
*/
|
|
131
|
-
async createIndexFileRecursively(chunkHashes) {
|
|
132
|
-
// Create JSON content with chunk hashes
|
|
133
|
-
const indexContent = JSON.stringify(chunkHashes);
|
|
134
|
-
const indexBuffer = Buffer.from(indexContent, "utf8");
|
|
135
|
-
// Generate a new file ID for the index file
|
|
136
|
-
const indexFileId = (0, utils_1.newid)();
|
|
137
|
-
// Create metadata for the index file
|
|
138
|
-
const indexMetadata = {
|
|
139
|
-
fileId: indexFileId,
|
|
140
|
-
name: `index-${indexFileId}.json`,
|
|
141
|
-
fileSize: indexBuffer.length,
|
|
142
|
-
mimeType: "application/json",
|
|
143
|
-
isIndexFile: true,
|
|
144
|
-
};
|
|
145
|
-
// Recursively save the index file (this will chunk it if it's too large)
|
|
146
|
-
await this.saveFile(indexMetadata, indexBuffer);
|
|
147
|
-
return indexFileId;
|
|
148
|
-
}
|
|
149
|
-
/**
|
|
150
|
-
* Read a large file's chunk hashes back from its index file.
|
|
151
|
-
*
|
|
152
|
-
* @param indexFileId - The index file's id.
|
|
153
|
-
* @returns The chunk hashes, in order.
|
|
138
|
+
* @param fileId - File to delete. A missing file is not an error.
|
|
139
|
+
* @throws When the file isn't a legacy bundle row.
|
|
154
140
|
*/
|
|
155
|
-
async
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
throw new Error(`Index file not found: ${indexFileId}`);
|
|
141
|
+
async deleteFile(fileId) {
|
|
142
|
+
const fileRecord = await super.get(fileId);
|
|
143
|
+
if (!fileRecord) {
|
|
144
|
+
return;
|
|
160
145
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
return JSON.parse(indexContent);
|
|
146
|
+
(0, file_rows_1.checkFileWrite)(fileRecord, undefined, fileId);
|
|
147
|
+
await super.delete(fileId);
|
|
164
148
|
}
|
|
165
149
|
}
|
|
166
150
|
exports.FilesTable = FilesTable;
|
|
@@ -184,14 +168,8 @@ rpc_types_1.rpcServerCalls.getFileContentsBase64 = async (fileId) => {
|
|
|
184
168
|
return Buffer.from(data).toString("base64");
|
|
185
169
|
};
|
|
186
170
|
rpc_types_1.rpcServerCalls.saveFile = async (input) => {
|
|
187
|
-
const fileId = input.fileId || (0, utils_1.newid)();
|
|
188
171
|
const encoding = input.encoding || "utf8";
|
|
189
172
|
const dataBuffer = encoding === "base64" ? Buffer.from(input.data, "base64") : Buffer.from(input.data, "utf8");
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
name: input.name,
|
|
193
|
-
fileSize: dataBuffer.length,
|
|
194
|
-
mimeType: input.mimeType,
|
|
195
|
-
}, new Uint8Array(dataBuffer));
|
|
196
|
-
return file;
|
|
173
|
+
// Kept: Family Hub 0.3.x doesn't declare its file fields, so nothing would reference these.
|
|
174
|
+
return await Files().saveFile({ name: input.name, mimeType: input.mimeType, keep: true }, new Uint8Array(dataBuffer));
|
|
197
175
|
};
|
package/dist/data/files/index.js
CHANGED
|
@@ -15,9 +15,11 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
exports.FileWriteStream = exports.FileReadStream = void 0;
|
|
18
|
+
__exportStar(require("./chunk-store"), exports);
|
|
18
19
|
__exportStar(require("./file.types"), exports);
|
|
19
20
|
var file_read_stream_1 = require("./file-read-stream");
|
|
20
21
|
Object.defineProperty(exports, "FileReadStream", { enumerable: true, get: function () { return file_read_stream_1.FileReadStream; } });
|
|
22
|
+
__exportStar(require("./file-rows"), exports);
|
|
21
23
|
var file_write_stream_1 = require("./file-write-stream");
|
|
22
24
|
Object.defineProperty(exports, "FileWriteStream", { enumerable: true, get: function () { return file_write_stream_1.FileWriteStream; } });
|
|
23
25
|
__exportStar(require("./files"), exports);
|
package/dist/data/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export * from "./authority-write-checks";
|
|
|
4
4
|
export * from "./change-tracking";
|
|
5
5
|
export * from "./channels";
|
|
6
6
|
export * from "./create-group";
|
|
7
|
+
export * from "./derived-row-id";
|
|
7
8
|
export * from "./device-sync-info";
|
|
8
9
|
export * from "./devices";
|
|
9
10
|
export * from "./embeddings";
|
package/dist/data/index.js
CHANGED
|
@@ -20,6 +20,7 @@ __exportStar(require("./authority-write-checks"), exports);
|
|
|
20
20
|
__exportStar(require("./change-tracking"), exports);
|
|
21
21
|
__exportStar(require("./channels"), exports);
|
|
22
22
|
__exportStar(require("./create-group"), exports);
|
|
23
|
+
__exportStar(require("./derived-row-id"), exports);
|
|
23
24
|
__exportStar(require("./device-sync-info"), exports);
|
|
24
25
|
__exportStar(require("./devices"), exports);
|
|
25
26
|
__exportStar(require("./embeddings"), exports);
|
package/dist/data/messages.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import type { DataContext } from "../context/data-context";
|
|
3
|
+
/** A chat entry in a channel or thread, by a user or an assistant acting for them. */
|
|
3
4
|
export declare const messageSchema: z.ZodObject<{
|
|
4
5
|
messageId: z.ZodEffects<z.ZodString, string, string>;
|
|
5
6
|
channelId: z.ZodEffects<z.ZodString, string, string>;
|
|
@@ -34,7 +35,13 @@ export declare const messageSchema: z.ZodObject<{
|
|
|
34
35
|
fileIds?: string[] | undefined;
|
|
35
36
|
vars?: z.objectInputType<{}, z.ZodAny, "strip"> | undefined;
|
|
36
37
|
}>;
|
|
38
|
+
/** One row of the Messages table. */
|
|
37
39
|
export type IMessage = z.infer<typeof messageSchema>;
|
|
40
|
+
/**
|
|
41
|
+
* The Messages table in a data context.
|
|
42
|
+
*
|
|
43
|
+
* @param dataContext - The context to read; defaults to the active one.
|
|
44
|
+
*/
|
|
38
45
|
export declare function Messages(dataContext?: DataContext): import("..").Table<{
|
|
39
46
|
message: string;
|
|
40
47
|
userId: string;
|
|
@@ -52,6 +59,20 @@ interface ISendMessageArgs {
|
|
|
52
59
|
assistantId?: string;
|
|
53
60
|
messageContent: string;
|
|
54
61
|
}
|
|
62
|
+
/**
|
|
63
|
+
* Post a message as the current user. The target is a message (a reply goes in its thread), a
|
|
64
|
+
* workflow run (a reply to the message that started it), a channel, a group (its default
|
|
65
|
+
* channel), or a user.
|
|
66
|
+
*
|
|
67
|
+
* @param args - The target, the content, and the assistant posting it, if any.
|
|
68
|
+
* @returns The stored message.
|
|
69
|
+
*/
|
|
55
70
|
export declare function sendMessage(args: ISendMessageArgs): Promise<IMessage>;
|
|
71
|
+
/**
|
|
72
|
+
* The variables set on a message and on the message that started its thread, merged in the order
|
|
73
|
+
* they were created: a later message's value replaces an earlier one's.
|
|
74
|
+
*
|
|
75
|
+
* @param message - A message in the thread.
|
|
76
|
+
*/
|
|
56
77
|
export declare function getThreadVars(message: IMessage): Promise<Record<string, any>>;
|
|
57
78
|
export {};
|
package/dist/data/messages.js
CHANGED
|
@@ -14,6 +14,7 @@ const table_definitions_system_1 = require("./orm/table-definitions.system");
|
|
|
14
14
|
const types_1 = require("./orm/types");
|
|
15
15
|
const users_1 = require("./users");
|
|
16
16
|
const workflow_runs_1 = require("./workflow-runs");
|
|
17
|
+
/** A chat entry in a channel or thread, by a user or an assistant acting for them. */
|
|
17
18
|
exports.messageSchema = zod_1.z.object({
|
|
18
19
|
messageId: zod_types_1.zodPeerId,
|
|
19
20
|
channelId: zod_types_1.zodPeerId.describe("The id of the channel this message entry belongs to"),
|
|
@@ -30,7 +31,7 @@ exports.messageSchema = zod_1.z.object({
|
|
|
30
31
|
.date()
|
|
31
32
|
.optional()
|
|
32
33
|
.describe("The time this message entry was last edited, if it was edited"),
|
|
33
|
-
fileIds: zod_types_1.
|
|
34
|
+
fileIds: zod_types_1.zodFileId.array().optional().describe("The ids of files attached to this message entry"),
|
|
34
35
|
vars: zod_types_1.zodAnyObject
|
|
35
36
|
.optional()
|
|
36
37
|
.describe("The variables that are associated with this message entry"),
|
|
@@ -56,9 +57,22 @@ const metaData = {
|
|
|
56
57
|
],
|
|
57
58
|
};
|
|
58
59
|
(0, table_definitions_system_1.registerSystemTableDefinition)(metaData, exports.messageSchema);
|
|
60
|
+
/**
|
|
61
|
+
* The Messages table in a data context.
|
|
62
|
+
*
|
|
63
|
+
* @param dataContext - The context to read; defaults to the active one.
|
|
64
|
+
*/
|
|
59
65
|
function Messages(dataContext) {
|
|
60
66
|
return (0, user_context_singleton_1.getTableContainer)(dataContext).getTable(metaData, exports.messageSchema);
|
|
61
67
|
}
|
|
68
|
+
/**
|
|
69
|
+
* Post a message as the current user. The target is a message (a reply goes in its thread), a
|
|
70
|
+
* workflow run (a reply to the message that started it), a channel, a group (its default
|
|
71
|
+
* channel), or a user.
|
|
72
|
+
*
|
|
73
|
+
* @param args - The target, the content, and the assistant posting it, if any.
|
|
74
|
+
* @returns The stored message.
|
|
75
|
+
*/
|
|
62
76
|
async function sendMessage(args) {
|
|
63
77
|
const { channelOrThreadIdOrWorkflowRunId, assistantId, messageContent } = args;
|
|
64
78
|
let channelId = channelOrThreadIdOrWorkflowRunId;
|
|
@@ -98,6 +112,12 @@ async function sendMessage(args) {
|
|
|
98
112
|
});
|
|
99
113
|
return message;
|
|
100
114
|
}
|
|
115
|
+
/**
|
|
116
|
+
* The variables set on a message and on the message that started its thread, merged in the order
|
|
117
|
+
* they were created: a later message's value replaces an earlier one's.
|
|
118
|
+
*
|
|
119
|
+
* @param message - A message in the thread.
|
|
120
|
+
*/
|
|
101
121
|
async function getThreadVars(message) {
|
|
102
122
|
const $or = [{ messageId: message.messageId }];
|
|
103
123
|
if (message.messageParentId) {
|
|
@@ -19,7 +19,8 @@ export declare class SQLDataSource<T extends {
|
|
|
19
19
|
private buildTableSql;
|
|
20
20
|
private ensureTableAndIndexesExist;
|
|
21
21
|
private ensureTableIsNewest;
|
|
22
|
-
|
|
22
|
+
/** Shared initialization, reset by a subclass that atomically drops its table and derived data. */
|
|
23
|
+
protected tableBuild: Promise<boolean> | undefined;
|
|
23
24
|
/** Share schema initialization; a failed attempt is evicted so later calls can retry. */
|
|
24
25
|
initTable(force?: boolean): Promise<boolean>;
|
|
25
26
|
get(id: string): Promise<T | undefined>;
|
|
@@ -172,6 +172,7 @@ class SQLDataSource {
|
|
|
172
172
|
await this.ensureTableAndIndexesExist();
|
|
173
173
|
return false;
|
|
174
174
|
}
|
|
175
|
+
/** Shared initialization, reset by a subclass that atomically drops its table and derived data. */
|
|
175
176
|
tableBuild;
|
|
176
177
|
/** Share schema initialization; a failed attempt is evicted so later calls can retry. */
|
|
177
178
|
async initTable(force = false) {
|
package/dist/data/orm/types.js
CHANGED
|
@@ -65,6 +65,10 @@ function fieldValueSchema(field, mode, open) {
|
|
|
65
65
|
case "id": {
|
|
66
66
|
const id = zod_1.z.string().refine((value) => (0, utils_1.isid)(value), { message: "Invalid id" });
|
|
67
67
|
id._def._fieldType = field_type_1.FieldType.id;
|
|
68
|
+
// Keep a file reference a reference when a schema is rebuilt from stored fields.
|
|
69
|
+
if (field.subType) {
|
|
70
|
+
id._def._subType = field.subType;
|
|
71
|
+
}
|
|
68
72
|
return id;
|
|
69
73
|
}
|
|
70
74
|
case "string":
|
|
@@ -261,6 +265,7 @@ function schemaToFields(schema) {
|
|
|
261
265
|
let _def = field._def;
|
|
262
266
|
let isArray;
|
|
263
267
|
let brandedFieldType;
|
|
268
|
+
let brandedSubType;
|
|
264
269
|
while (true) {
|
|
265
270
|
if (_def.typeName === "ZodArray") {
|
|
266
271
|
if (isArray)
|
|
@@ -272,6 +277,9 @@ function schemaToFields(schema) {
|
|
|
272
277
|
if (_def._fieldType) {
|
|
273
278
|
brandedFieldType = _def._fieldType;
|
|
274
279
|
}
|
|
280
|
+
if (_def._subType) {
|
|
281
|
+
brandedSubType = _def._subType;
|
|
282
|
+
}
|
|
275
283
|
if (_def.typeName === "ZodNullable") {
|
|
276
284
|
nullable = true;
|
|
277
285
|
}
|
|
@@ -320,11 +328,15 @@ function schemaToFields(schema) {
|
|
|
320
328
|
// optional/defaulted elements and nested arrays: enumValues describes each immediate element.
|
|
321
329
|
const values = nullable || !enumElements ? undefined : zodEnumValues(valueSchema);
|
|
322
330
|
const enumValues = values?.length ? [...new Set(values)] : undefined;
|
|
331
|
+
// A subtype (`zodFileId`'s "file") describes the branded type, so it goes only where that
|
|
332
|
+
// type was kept.
|
|
333
|
+
const subType = brandedFieldType && type === brandedFieldType ? brandedSubType : undefined;
|
|
323
334
|
const newField = {
|
|
324
335
|
name,
|
|
325
336
|
type,
|
|
326
337
|
isArray,
|
|
327
338
|
optional,
|
|
339
|
+
subType,
|
|
328
340
|
description,
|
|
329
341
|
defaultValue,
|
|
330
342
|
enumValues,
|
|
@@ -58,11 +58,11 @@ const schema = zod_1.z.object({
|
|
|
58
58
|
version: zod_1.z.string().describe('Semantic version string (e.g., "1.0.0")'),
|
|
59
59
|
versionTag: zod_1.z.string().optional().describe('Version tag (e.g., "stable", "beta")'),
|
|
60
60
|
packageVersionHash: zod_1.z.string().describe("Hash of the combined bundle file hashes"),
|
|
61
|
-
packageBundleFileId: zod_types_1.
|
|
61
|
+
packageBundleFileId: zod_types_1.zodFileId.describe("File ID of the package bundle"),
|
|
62
62
|
packageBundleFileHash: zod_1.z.string().describe("Hash of the package bundle file"),
|
|
63
|
-
routesBundleFileId: zod_types_1.
|
|
63
|
+
routesBundleFileId: zod_types_1.zodFileId.optional().describe("File ID of the routes bundle"),
|
|
64
64
|
routesBundleFileHash: zod_1.z.string().optional().describe("Hash of the routes bundle"),
|
|
65
|
-
uiBundleFileId: zod_types_1.
|
|
65
|
+
uiBundleFileId: zod_types_1.zodFileId.optional().describe("File ID of the UI bundle"),
|
|
66
66
|
uiBundleFileHash: zod_1.z.string().optional().describe("Hash of the UI bundle"),
|
|
67
67
|
appNavs: app_nav_1.appNavSchema
|
|
68
68
|
.array()
|
package/dist/define/index.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ export { type Observable, observable, type Subscription } from "../observable";
|
|
|
14
14
|
export type { IPackageSaveOptions } from "../package-loader/isolated-runtime";
|
|
15
15
|
export { idFromKey, isid, newid } from "../peer-id";
|
|
16
16
|
export { FieldType, type IField } from "../types/field-type";
|
|
17
|
-
export { zodPeerId } from "../types/zod-types";
|
|
17
|
+
export { zodFileId, zodPeerId } from "../types/zod-types";
|
|
18
18
|
export * from "./context";
|
|
19
19
|
export * from "./contract-ref";
|
|
20
20
|
export * from "./declare-contract";
|
package/dist/define/index.js
CHANGED
|
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.writePackageVar = exports.userVar = exports.readPackageVar = exports.groupVar = exports.groupUserVar = exports.groupDeviceVar = exports.deviceVar = exports.isImplementedObservable = exports.defineObservable = exports.declareObservable = exports.generatedField = exports.defineEvent = exports.zodPeerId = exports.FieldType = exports.newid = exports.isid = exports.idFromKey = exports.observable = exports.AccessLevel = exports.z = void 0;
|
|
17
|
+
exports.writePackageVar = exports.userVar = exports.readPackageVar = exports.groupVar = exports.groupUserVar = exports.groupDeviceVar = exports.deviceVar = exports.isImplementedObservable = exports.defineObservable = exports.declareObservable = exports.generatedField = exports.defineEvent = exports.zodPeerId = exports.zodFileId = exports.FieldType = exports.newid = exports.isid = exports.idFromKey = exports.observable = exports.AccessLevel = exports.z = void 0;
|
|
18
18
|
/**
|
|
19
19
|
* `@peers-app/peers-sdk/define`: declare an isolated package.
|
|
20
20
|
*
|
|
@@ -36,6 +36,7 @@ Object.defineProperty(exports, "newid", { enumerable: true, get: function () { r
|
|
|
36
36
|
var field_type_1 = require("../types/field-type");
|
|
37
37
|
Object.defineProperty(exports, "FieldType", { enumerable: true, get: function () { return field_type_1.FieldType; } });
|
|
38
38
|
var zod_types_1 = require("../types/zod-types");
|
|
39
|
+
Object.defineProperty(exports, "zodFileId", { enumerable: true, get: function () { return zod_types_1.zodFileId; } });
|
|
39
40
|
Object.defineProperty(exports, "zodPeerId", { enumerable: true, get: function () { return zod_types_1.zodPeerId; } });
|
|
40
41
|
__exportStar(require("./context"), exports);
|
|
41
42
|
__exportStar(require("./contract-ref"), exports);
|
|
@@ -140,10 +140,17 @@ export declare const SystemContractCatalog: import("./contract-ref").IContractRe
|
|
|
140
140
|
}>;
|
|
141
141
|
/**
|
|
142
142
|
* System Files v1: save a file and read it back, in the package's own data context. Files sync
|
|
143
|
-
* to the context's other devices. Declare it with `pkg.consumes(SystemFiles)
|
|
143
|
+
* to the context's other devices. Declare it with `pkg.consumes(SystemFiles)`; save a file over
|
|
144
|
+
* 8 MiB with {@link saveWholeFile}.
|
|
144
145
|
*/
|
|
145
146
|
export declare const SystemFiles: import("./contract-ref").IContractRef<{
|
|
146
147
|
save(input: import("../contracts/system/files-shared").IFilesSaveInput): Promise<import("../contracts/system/files-shared").IFilesSaveResult>;
|
|
147
148
|
read(input: import("../contracts/system/files-shared").IFilesReadInput): Promise<import("../contracts/system/files-shared").IFilesReadResult>;
|
|
149
|
+
startSave(input: import("../contracts/system/files-shared").IFilesStartSaveInput): Promise<import("../contracts/system/files-shared").IFilesSaveSession>;
|
|
150
|
+
appendSave(input: import("../contracts/system/files-shared").IFilesAppendSaveInput): Promise<import("../contracts/system/files-shared").IFilesAppendSaveResult>;
|
|
151
|
+
finishSave(input: import("../contracts/system/files-shared").IFilesSaveSession): Promise<import("../contracts/system/files-shared").IFilesSaveResult>;
|
|
152
|
+
cancelSave(input: import("../contracts/system/files-shared").IFilesSaveSession): Promise<{
|
|
153
|
+
cancelled: boolean;
|
|
154
|
+
}>;
|
|
148
155
|
}>;
|
|
149
|
-
export { FILES_MAX_CALL_BYTES, type IFilesReadInput, type IFilesReadResult, type IFilesSaveInput, type IFilesSaveResult, readWholeFile, } from "../contracts/system/files-shared";
|
|
156
|
+
export { FILES_MAX_CALL_BYTES, FILES_MAX_FILE_BYTES, FILES_WHOLE_READ_MAX_BYTES, type FileBytesSource, type IFilesAppendSaveInput, type IFilesAppendSaveResult, type IFilesReadInput, type IFilesReadResult, type IFilesSaveInput, type IFilesSaveResult, type IFilesSaveSession, type IFilesStartSaveInput, readWholeFile, saveWholeFile, } from "../contracts/system/files-shared";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.readWholeFile = exports.FILES_MAX_CALL_BYTES = exports.SystemFiles = exports.SystemContractCatalog = exports.SystemScheduler = exports.SystemGroupMembers = exports.SystemIdentity = exports.SystemHttp = void 0;
|
|
3
|
+
exports.saveWholeFile = exports.readWholeFile = exports.FILES_WHOLE_READ_MAX_BYTES = exports.FILES_MAX_FILE_BYTES = exports.FILES_MAX_CALL_BYTES = exports.SystemFiles = exports.SystemContractCatalog = exports.SystemScheduler = exports.SystemGroupMembers = exports.SystemIdentity = exports.SystemHttp = void 0;
|
|
4
4
|
const system_ids_1 = require("../system-ids");
|
|
5
5
|
const contract_ref_1 = require("./contract-ref");
|
|
6
6
|
/**
|
|
@@ -25,9 +25,13 @@ exports.SystemScheduler = (0, contract_ref_1.contractRef)(system_ids_1.scheduler
|
|
|
25
25
|
exports.SystemContractCatalog = (0, contract_ref_1.contractRef)(system_ids_1.contractCatalogContractId, 1);
|
|
26
26
|
/**
|
|
27
27
|
* System Files v1: save a file and read it back, in the package's own data context. Files sync
|
|
28
|
-
* to the context's other devices. Declare it with `pkg.consumes(SystemFiles)
|
|
28
|
+
* to the context's other devices. Declare it with `pkg.consumes(SystemFiles)`; save a file over
|
|
29
|
+
* 8 MiB with {@link saveWholeFile}.
|
|
29
30
|
*/
|
|
30
31
|
exports.SystemFiles = (0, contract_ref_1.contractRef)(system_ids_1.filesContractId, 1);
|
|
31
32
|
var files_shared_1 = require("../contracts/system/files-shared");
|
|
32
33
|
Object.defineProperty(exports, "FILES_MAX_CALL_BYTES", { enumerable: true, get: function () { return files_shared_1.FILES_MAX_CALL_BYTES; } });
|
|
34
|
+
Object.defineProperty(exports, "FILES_MAX_FILE_BYTES", { enumerable: true, get: function () { return files_shared_1.FILES_MAX_FILE_BYTES; } });
|
|
35
|
+
Object.defineProperty(exports, "FILES_WHOLE_READ_MAX_BYTES", { enumerable: true, get: function () { return files_shared_1.FILES_WHOLE_READ_MAX_BYTES; } });
|
|
33
36
|
Object.defineProperty(exports, "readWholeFile", { enumerable: true, get: function () { return files_shared_1.readWholeFile; } });
|
|
37
|
+
Object.defineProperty(exports, "saveWholeFile", { enumerable: true, get: function () { return files_shared_1.saveWholeFile; } });
|
|
@@ -1630,8 +1630,8 @@ export declare const devicePairingStateSchema: z.ZodObject<{
|
|
|
1630
1630
|
code?: string | undefined;
|
|
1631
1631
|
error?: string | undefined;
|
|
1632
1632
|
role?: "source" | "destination" | undefined;
|
|
1633
|
-
expiresAt?: number | undefined;
|
|
1634
1633
|
sessionId?: string | undefined;
|
|
1634
|
+
expiresAt?: number | undefined;
|
|
1635
1635
|
remoteDevice?: {
|
|
1636
1636
|
userName?: string | undefined;
|
|
1637
1637
|
deviceName?: string | undefined;
|
|
@@ -1643,8 +1643,8 @@ export declare const devicePairingStateSchema: z.ZodObject<{
|
|
|
1643
1643
|
code?: string | undefined;
|
|
1644
1644
|
error?: string | undefined;
|
|
1645
1645
|
role?: "source" | "destination" | undefined;
|
|
1646
|
-
expiresAt?: number | undefined;
|
|
1647
1646
|
sessionId?: string | undefined;
|
|
1647
|
+
expiresAt?: number | undefined;
|
|
1648
1648
|
remoteDevice?: {
|
|
1649
1649
|
userName?: string | undefined;
|
|
1650
1650
|
deviceName?: string | undefined;
|
|
@@ -15,6 +15,8 @@ export interface IPackageBuildResult {
|
|
|
15
15
|
artifactPath: string;
|
|
16
16
|
/** Size of the bundled provider source, in characters. */
|
|
17
17
|
providerChars: number;
|
|
18
|
+
/** Things the build accepted but the author likely didn't mean ({@link fileFieldWarnings}). */
|
|
19
|
+
warnings: string[];
|
|
18
20
|
}
|
|
19
21
|
/** A running package watcher. Dispose it to stop watching and release esbuild. */
|
|
20
22
|
export interface IPackageWatcher {
|
|
@@ -28,6 +30,15 @@ export interface IPackageWatcher {
|
|
|
28
30
|
* @param entry - The module's path.
|
|
29
31
|
*/
|
|
30
32
|
export declare function loadPackageModule(root: string, entry: string): Promise<unknown>;
|
|
33
|
+
/**
|
|
34
|
+
* Warnings about table fields that look like file references but aren't: a top-level field
|
|
35
|
+
* named like a file id that isn't declared with `zodFileId`, and a `zodFileId` nested in an
|
|
36
|
+
* object field. Neither keeps its files, so Peers may free them. Internal to the build.
|
|
37
|
+
*
|
|
38
|
+
* @internal
|
|
39
|
+
* @param manifest - The package's manifest.
|
|
40
|
+
*/
|
|
41
|
+
export declare function fileFieldWarnings(manifest: IIsolatedPackageManifest): string[];
|
|
31
42
|
/**
|
|
32
43
|
* The generate-manifest step: write `dist/manifest.json` from the package's declarations.
|
|
33
44
|
*
|
|
@@ -36,6 +47,7 @@ export declare function loadPackageModule(root: string, entry: string): Promise<
|
|
|
36
47
|
export declare function generatePackageManifest(buildOptions?: IPackageBuildOptions): Promise<{
|
|
37
48
|
manifest: IIsolatedPackageManifest;
|
|
38
49
|
manifestPath: string;
|
|
50
|
+
warnings: string[];
|
|
39
51
|
}>;
|
|
40
52
|
/**
|
|
41
53
|
* Build the package's manifest from its declarations, validated, without writing it or checking
|