@weaveprotocol/cli 0.2.3 → 0.2.4
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/weave.mjs +28 -3
- package/package.json +1 -1
package/dist/weave.mjs
CHANGED
|
@@ -12942,7 +12942,8 @@ var app = {
|
|
|
12942
12942
|
title: { type: "string", minLength: 1, maxLength: 100 },
|
|
12943
12943
|
description: { type: "string", maxLength: 1e3 },
|
|
12944
12944
|
needs: { type: "array", minItems: 1, maxItems: MAX_APP_COLLECTIONS, items: { type: "object" } },
|
|
12945
|
-
from: { type: "string", maxLength: 300 }
|
|
12945
|
+
from: { type: "string", maxLength: 300 },
|
|
12946
|
+
updates: { type: "string", minLength: 1, maxLength: 100 }
|
|
12946
12947
|
},
|
|
12947
12948
|
required: ["title", "needs"]
|
|
12948
12949
|
},
|
|
@@ -12956,6 +12957,9 @@ function checkApp(value) {
|
|
|
12956
12957
|
if (body.description !== void 0 && (typeof body.description !== "string" || body.description.length > 1e3)) {
|
|
12957
12958
|
return "An app's description is at most 1000 characters";
|
|
12958
12959
|
}
|
|
12960
|
+
if (body.updates !== void 0 && (typeof body.updates !== "string" || !body.updates || body.updates.length > 100)) {
|
|
12961
|
+
return `An app's "updates" is the key of the app it replaces`;
|
|
12962
|
+
}
|
|
12959
12963
|
if (!Array.isArray(body.needs) || body.needs.length === 0 || body.needs.length > MAX_APP_COLLECTIONS) {
|
|
12960
12964
|
return `An app needs 1\u2013${MAX_APP_COLLECTIONS} collections`;
|
|
12961
12965
|
}
|
|
@@ -13031,9 +13035,25 @@ function reviewApp(body, collections) {
|
|
|
13031
13035
|
});
|
|
13032
13036
|
return { needs, added: needs.every((need) => need.status === "same"), problem: null };
|
|
13033
13037
|
}
|
|
13038
|
+
function supersededApps(records, collections) {
|
|
13039
|
+
const replaces = /* @__PURE__ */ new Map();
|
|
13040
|
+
for (const record of records) {
|
|
13041
|
+
if (record.body?.updates && record.body.updates !== record.key) replaces.set(record.key, record.body.updates);
|
|
13042
|
+
}
|
|
13043
|
+
const superseded = /* @__PURE__ */ new Set();
|
|
13044
|
+
for (const record of records) {
|
|
13045
|
+
if (!record.body || !reviewApp(record.body, collections).added) continue;
|
|
13046
|
+
for (let key3 = replaces.get(record.key); key3 && !superseded.has(key3) && key3 !== record.key; key3 = replaces.get(key3)) superseded.add(key3);
|
|
13047
|
+
}
|
|
13048
|
+
return superseded;
|
|
13049
|
+
}
|
|
13034
13050
|
async function proposeApp(node, spaceId, body) {
|
|
13035
13051
|
const problem = checkApp(body);
|
|
13036
13052
|
if (problem) throw new Error(problem);
|
|
13053
|
+
if (body.updates) {
|
|
13054
|
+
const replaced = await node.records.get(spaceId, body.updates);
|
|
13055
|
+
if (!replaced || replaced.collection !== app.name) throw new Error(`"updates" names no app in this space: ${body.updates}`);
|
|
13056
|
+
}
|
|
13037
13057
|
return node.records.put(spaceId, app.name, body);
|
|
13038
13058
|
}
|
|
13039
13059
|
|
|
@@ -13280,7 +13300,7 @@ var NODE_ACTIONS = Object.freeze([
|
|
|
13280
13300
|
},
|
|
13281
13301
|
{
|
|
13282
13302
|
name: "apps_list",
|
|
13283
|
-
description: 'The apps proposed in a space: each with its title, who proposed it (viaAgent when an agent did), and for every collection it needs whether it is new, already there, or would change one \u2014 with what it allows, worked out from its rules. "added" is true once a person has added it.',
|
|
13303
|
+
description: 'The apps proposed in a space: each with its title, who proposed it (viaAgent when an agent did), and for every collection it needs whether it is new, already there, or would change one \u2014 with what it allows, worked out from its rules. "added" is true once a person has added it. "updates" names the app it is a new version of; "superseded" is true once a newer version of it has been added, so it is only history.',
|
|
13284
13304
|
input: { type: "object", properties: { space }, required: ["space"] },
|
|
13285
13305
|
readOnly: true,
|
|
13286
13306
|
peerContent: true,
|
|
@@ -13288,6 +13308,7 @@ var NODE_ACTIONS = Object.freeze([
|
|
|
13288
13308
|
const spaceId = str(input, "space");
|
|
13289
13309
|
const collections = await node.collections.list(spaceId);
|
|
13290
13310
|
const found = await node.records.list(spaceId, { collection: app.name });
|
|
13311
|
+
const superseded = supersededApps(found, collections);
|
|
13291
13312
|
return found.map((record) => {
|
|
13292
13313
|
const review = record.body ? reviewApp(record.body, collections) : null;
|
|
13293
13314
|
return {
|
|
@@ -13297,7 +13318,9 @@ var NODE_ACTIONS = Object.freeze([
|
|
|
13297
13318
|
proposedBy: record.createdBy,
|
|
13298
13319
|
...record.viaAgent ? { viaAgent: true } : {},
|
|
13299
13320
|
...record.body && appScreen(record.body) ? { screen: appScreen(record.body).collection } : {},
|
|
13321
|
+
...record.body?.updates ? { updates: record.body.updates } : {},
|
|
13300
13322
|
added: review?.added ?? false,
|
|
13323
|
+
superseded: superseded.has(record.key),
|
|
13301
13324
|
problem: review?.problem ?? (record.body ? null : "It could not be read"),
|
|
13302
13325
|
needs: review?.needs.map(({ definition, status, summary, changes }) => ({ name: definition.name, status, summary, changes })) ?? []
|
|
13303
13326
|
};
|
|
@@ -13313,13 +13336,14 @@ var NODE_ACTIONS = Object.freeze([
|
|
|
13313
13336
|
},
|
|
13314
13337
|
{
|
|
13315
13338
|
name: "apps_propose",
|
|
13316
|
-
description: `Propose an app in a space: a new way for its people to work together \u2014 a carpool, a sign-up sheet, a decision log. Give it a title, a line on what it is for, and the collections it needs, each exactly as collections_define takes it (name, title, description, schema, links, permissions, rules \u2014 no version). Nothing is defined yet: everyone in the space sees the proposal, with what it allows worked out from its rules, and a person who may define collections adds it. Read collections_list first and reuse what the space already has (std.poll, std.task\u2026) rather than inventing a twin. For anything plain lists and forms can't show \u2014 a game board, a calendar, a whiteboard \u2014 give the main collection a "screen": its own HTML UI (one document, inline scripts and styles, no network unless the collection names exact origins in "network"). Inside it, use exactly: weave.me ({ did, name }), await weave.list("<collection>", { where: { "link:<rel>": key } }), await weave.put("<collection>", body, { links: [{ rel, to: key }] }), await weave.update(key, body), await weave.remove(key), weave.onChange(redraw). Records are { key, body, links, createdBy, mine }. Read apps_screen_guide for the rest. Returns what each collection will allow; tell the person that, not your own description.`,
|
|
13339
|
+
description: `Propose an app in a space: a new way for its people to work together \u2014 a carpool, a sign-up sheet, a decision log. Give it a title, a line on what it is for, and the collections it needs, each exactly as collections_define takes it (name, title, description, schema, links, permissions, rules \u2014 no version). Nothing is defined yet: everyone in the space sees the proposal, with what it allows worked out from its rules, and a person who may define collections adds it. Read collections_list first and reuse what the space already has (std.poll, std.task\u2026) rather than inventing a twin. To change an app that is already here, read apps_list and pass the key of its newest version, the one not superseded, as "updates": the change then shows as an update to it, and once it is added the old version is not offered again. For anything plain lists and forms can't show \u2014 a game board, a calendar, a whiteboard \u2014 give the main collection a "screen": its own HTML UI (one document, inline scripts and styles, no network unless the collection names exact origins in "network"). Inside it, use exactly: weave.me ({ did, name }), await weave.list("<collection>", { where: { "link:<rel>": key } }), await weave.put("<collection>", body, { links: [{ rel, to: key }] }), await weave.update(key, body), await weave.remove(key), weave.onChange(redraw). Records are { key, body, links, createdBy, mine }. Read apps_screen_guide for the rest. Returns what each collection will allow; tell the person that, not your own description.`,
|
|
13317
13340
|
input: {
|
|
13318
13341
|
type: "object",
|
|
13319
13342
|
properties: {
|
|
13320
13343
|
space,
|
|
13321
13344
|
title: { type: "string", description: 'What people will call it, e.g. "Carpool"' },
|
|
13322
13345
|
description: { type: "string", description: "What it is for, in a sentence" },
|
|
13346
|
+
updates: { type: "string", description: "The key of the app this is a new version of, from apps_list" },
|
|
13323
13347
|
needs: {
|
|
13324
13348
|
type: "array",
|
|
13325
13349
|
description: "Collection definitions, as collections_define takes them \u2014 without version",
|
|
@@ -13334,6 +13358,7 @@ var NODE_ACTIONS = Object.freeze([
|
|
|
13334
13358
|
const body = {
|
|
13335
13359
|
title: str(input, "title"),
|
|
13336
13360
|
...typeof input.description === "string" ? { description: input.description } : {},
|
|
13361
|
+
...typeof input.updates === "string" ? { updates: input.updates } : {},
|
|
13337
13362
|
needs: input.needs
|
|
13338
13363
|
};
|
|
13339
13364
|
const problem = checkApp(body);
|