@peers-app/peers-ui 0.19.9 → 0.19.12

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.
@@ -189,10 +189,9 @@ function CreateGroupModal({ colorMode, userContext, onClose, onGroupCreated, })
189
189
  signature: "", // Will be set by signAndSave()
190
190
  });
191
191
  await (0, peers_sdk_1.Groups)(groupDataContext).signAndSave(newGroup);
192
- // Auto-install peers-core for the new group
193
- await peers_sdk_1.rpcServerCalls
194
- .addOrUpdatePackage(peers_sdk_1.peersCorePackageId, { dataContextId: groupId })
195
- .catch((err) => {
192
+ // Auto-install peers-core for the new group (copy from another context that
193
+ // already has it, else fall back to the remote updateUrl / bundle).
194
+ await peers_sdk_1.rpcServerCalls.seedBundledPeersCore(groupId).catch((err) => {
196
195
  console.error("Error auto-installing peers-core for group:", err);
197
196
  });
198
197
  // Notify parent
@@ -56,7 +56,8 @@ const PackageDetails = (props) => {
56
56
  });
57
57
  }
58
58
  return ((0, jsx_runtime_1.jsxs)("div", { className: "container-fluid p-3", children: [(0, jsx_runtime_1.jsxs)("div", { className: "d-flex", children: [(0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)("h4", { children: (0, jsx_runtime_1.jsx)("i", { className: "bi bi-box-fill me-2" }) }) }), (0, jsx_runtime_1.jsx)("div", { className: "flex-grow-1", children: (0, jsx_runtime_1.jsx)("h4", { children: (0, jsx_runtime_1.jsx)(input_1.Input, { className: "border border-0", style: { width: "100%", outline: "none", backgroundColor: "transparent" }, value: pkg.qs.name }, pkg.packageId) }) }), (0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(save_button_1.SaveButton, { doc: pkg, onClick: async () => {
59
- await pkg.save();
59
+ await (0, peers_sdk_1.Packages)().signAndSave(pkg.toJS());
60
+ pkg.q(0);
60
61
  }, addActions: [...addActions] }, pkg.packageId) })] }), (0, jsx_runtime_1.jsx)(tabs_1.Tabs, { tabs: [
61
62
  {
62
63
  name: "Info",
@@ -72,7 +72,7 @@ const PackageInfo = (props) => {
72
72
  peers_sdk_1.rpcServerCalls.openPackage(localPath || peers_sdk_1.packagesRootDir);
73
73
  }, children: "Open Local" })] })] }), (0, jsx_runtime_1.jsx)("input", { type: "text", className: "form-control mb-3 p-0 ps-2", placeholder: "~/peers/packages/my-package", value: localPath || "", onChange: (e) => setLocalPath(e.target.value) })] }), remoteRepoUrl ? ((0, jsx_runtime_1.jsxs)("div", { className: "mt-2", children: [(0, jsx_runtime_1.jsxs)("small", { children: ["Source URL:", (0, jsx_runtime_1.jsxs)("small", { children: [(0, jsx_runtime_1.jsx)(tooltip_1.Tooltip, { markdownContent: `The remote source of this package. Often a github repository URL or a link to the Peers page for the package.` }), (0, jsx_runtime_1.jsx)("button", { className: "btn btn-sm btn-link", onClick: () => {
74
74
  peers_sdk_1.rpcServerCalls.openLinkInBrowser(remoteRepoUrl);
75
- }, children: "Open Remote" })] })] }), (0, jsx_runtime_1.jsx)(input_1.Input, { value: pkg.qs.remoteRepo, className: "form-control mb-3 p-0 ps-2", disabled: true })] })) : null, (0, jsx_runtime_1.jsxs)("div", { className: "mt-2", children: [(0, jsx_runtime_1.jsx)("hr", {}), (0, jsx_runtime_1.jsxs)("small", { children: ["Version:", (0, jsx_runtime_1.jsx)(tooltip_1.Tooltip, { markdownContent: "The currently active version of this package. Manage versions in the Versions tab." })] }), activeVersion ? ((0, jsx_runtime_1.jsxs)("div", { className: "d-flex align-items-center mt-1 mb-3", children: [(0, jsx_runtime_1.jsxs)("strong", { className: "me-2", children: ["v", activeVersion.version] }), activeVersion.versionTag && ((0, jsx_runtime_1.jsx)("span", { className: `badge ${activeVersion.versionTag === "dev" ? "text-bg-danger" : activeVersion.versionTag.startsWith("beta") ? "text-bg-warning" : "text-bg-success"} me-2`, children: activeVersion.versionTag })), (0, jsx_runtime_1.jsx)("code", { className: "text-muted small me-2", children: activeVersion.packageVersionHash?.substring(0, 8) }), newerLevel === "uptodate" ? ((0, jsx_runtime_1.jsx)("span", { className: "badge text-bg-success", children: "Up to date" })) : newerLevel ? ((0, jsx_runtime_1.jsxs)("span", { className: `badge text-bg-${newerLevel === "major" ? "danger" : newerLevel === "minor" ? "warning" : "info"}`, children: ["Newer ", newerLevel, " version available"] })) : null] })) : ((0, jsx_runtime_1.jsx)("div", { className: "text-muted small mt-1 mb-3", children: "No active version" })), (0, jsx_runtime_1.jsxs)("div", { className: "mb-3", children: [(0, jsx_runtime_1.jsxs)("small", { children: ["Auto-Update Range:", (0, jsx_runtime_1.jsx)(tooltip_1.Tooltip, { markdownContent: "Controls which new versions are auto-activated for the group. When an admin device auto-upgrades, the group's active version advances for everyone. **Pinned** = never auto-update. **Patch** = same major.minor (e.g. 1.2.x). **Minor** = same major (e.g. 1.x.x). **Latest** = always auto-update to newest." })] }), (0, jsx_runtime_1.jsxs)("select", { className: "form-select form-select-sm", value: groupRange, onChange: async (e) => {
75
+ }, children: "Open Remote" })] })] }), (0, jsx_runtime_1.jsx)(input_1.Input, { value: pkg.qs.remoteRepo, className: "form-control mb-3 p-0 ps-2", disabled: true })] })) : null, (0, jsx_runtime_1.jsxs)("div", { className: "mt-2", children: [(0, jsx_runtime_1.jsxs)("small", { children: ["Update URL:", (0, jsx_runtime_1.jsx)("small", { children: (0, jsx_runtime_1.jsx)(tooltip_1.Tooltip, { markdownContent: `Base URL for remote package updates. Admin devices poll **<updateUrl>/latest-<tag>.json** on startup (for example **latest-stable.json**). Signed artifacts must be published to this host separately — for example via the publish-package tool or the peers-core full-release pipeline.` }) })] }), (0, jsx_runtime_1.jsx)(input_1.Input, { value: pkg.qs.updateUrl, className: "form-control mb-3 p-0 ps-2", placeholder: "https://example.com/my-package", title: "Update URL" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "mt-2", children: [(0, jsx_runtime_1.jsx)("hr", {}), (0, jsx_runtime_1.jsxs)("small", { children: ["Version:", (0, jsx_runtime_1.jsx)(tooltip_1.Tooltip, { markdownContent: "The currently active version of this package. Manage versions in the Versions tab." })] }), activeVersion ? ((0, jsx_runtime_1.jsxs)("div", { className: "d-flex align-items-center mt-1 mb-3", children: [(0, jsx_runtime_1.jsxs)("strong", { className: "me-2", children: ["v", activeVersion.version] }), activeVersion.versionTag && ((0, jsx_runtime_1.jsx)("span", { className: `badge ${activeVersion.versionTag === "dev" ? "text-bg-danger" : activeVersion.versionTag.startsWith("beta") ? "text-bg-warning" : "text-bg-success"} me-2`, children: activeVersion.versionTag })), (0, jsx_runtime_1.jsx)("code", { className: "text-muted small me-2", children: activeVersion.packageVersionHash?.substring(0, 8) }), newerLevel === "uptodate" ? ((0, jsx_runtime_1.jsx)("span", { className: "badge text-bg-success", children: "Up to date" })) : newerLevel ? ((0, jsx_runtime_1.jsxs)("span", { className: `badge text-bg-${newerLevel === "major" ? "danger" : newerLevel === "minor" ? "warning" : "info"}`, children: ["Newer ", newerLevel, " version available"] })) : null] })) : ((0, jsx_runtime_1.jsx)("div", { className: "text-muted small mt-1 mb-3", children: "No active version" })), (0, jsx_runtime_1.jsxs)("div", { className: "mb-3", children: [(0, jsx_runtime_1.jsxs)("small", { children: ["Auto-Update Range:", (0, jsx_runtime_1.jsx)(tooltip_1.Tooltip, { markdownContent: "Controls which new versions are auto-activated for the group. When an admin device auto-upgrades, the group's active version advances for everyone. **Pinned** = never auto-update. **Patch** = same major.minor (e.g. 1.2.x). **Minor** = same major (e.g. 1.x.x). **Latest** = always auto-update to newest." })] }), (0, jsx_runtime_1.jsxs)("select", { className: "form-select form-select-sm", value: groupRange, onChange: async (e) => {
76
76
  const val = e.target.value;
77
77
  const current = await (0, peers_sdk_1.Packages)().get(pkg.packageId);
78
78
  if (current) {
@@ -105,10 +105,12 @@ const ProfileSection = () => {
105
105
  }, [deviceId, deviceName, savedDeviceName]);
106
106
  const handleSave = async () => {
107
107
  try {
108
- // Save user profile
109
- if (me) {
108
+ // Save user profile (only when it actually changed). Pass me.toJS() — the
109
+ // raw doc's fields are non-enumerable getters that get dropped when the
110
+ // signAndSave call is serialized to JSON over the socket to the server.
111
+ if (me?.q()) {
110
112
  const userContext = await (0, peers_sdk_1.getUserContext)();
111
- await (0, peers_sdk_1.Users)(userContext.userDataContext).signAndSave(me);
113
+ await (0, peers_sdk_1.Users)(userContext.userDataContext).signAndSave(me.toJS());
112
114
  me.q(0); // Reset change counter
113
115
  }
114
116
  // Save device name if changed
@@ -23,14 +23,9 @@ const SetupUser = () => {
23
23
  // Generate new user credentials
24
24
  const keys = (0, peers_sdk_1.newKeys)();
25
25
  const _userId = (0, peers_sdk_1.newid)();
26
- // Call setUserIdAndSecretKey
26
+ // Call setUserIdAndSecretKey. This triggers device init, which installs
27
+ // peers-core into the personal context (S3-first, bundle fallback).
27
28
  await peers_sdk_1.rpcServerCalls.setUserIdAndSecretKey(_userId, keys.secretKey);
28
- // Auto-install peers-core for the new user
29
- await peers_sdk_1.rpcServerCalls
30
- .addOrUpdatePackage(peers_sdk_1.peersCorePackageId, { dataContextId: _userId })
31
- .catch((err) => {
32
- console.error("Error auto-installing peers-core:", err);
33
- });
34
29
  // Success - reload the app (peers-services registration runs after Welcome modal)
35
30
  window.location.reload();
36
31
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@peers-app/peers-ui",
3
- "version": "0.19.9",
3
+ "version": "0.19.12",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/peers-app/peers-ui.git"
@@ -28,7 +28,7 @@
28
28
  "lint:fix": "biome check --write ."
29
29
  },
30
30
  "peerDependencies": {
31
- "@peers-app/peers-sdk": "^0.19.9",
31
+ "@peers-app/peers-sdk": "^0.19.12",
32
32
  "bootstrap": "^5.3.3",
33
33
  "react": "^18.0.0",
34
34
  "react-dom": "^18.0.0"
@@ -39,7 +39,7 @@
39
39
  "@babel/preset-env": "^7.24.5",
40
40
  "@babel/preset-react": "^7.24.1",
41
41
  "@babel/preset-typescript": "^7.27.1",
42
- "@peers-app/peers-sdk": "0.19.9",
42
+ "@peers-app/peers-sdk": "0.19.12",
43
43
  "@testing-library/dom": "^10.4.0",
44
44
  "@testing-library/jest-dom": "^6.6.3",
45
45
  "@testing-library/react": "^16.3.0",
@@ -5,7 +5,6 @@ import {
5
5
  type IGroup,
6
6
  newid,
7
7
  newKeys,
8
- peersCorePackageId,
9
8
  rpcServerCalls,
10
9
  setUserTrustLevel,
11
10
  TrustLevel,
@@ -293,12 +292,11 @@ function CreateGroupModal({
293
292
 
294
293
  await Groups(groupDataContext).signAndSave(newGroup);
295
294
 
296
- // Auto-install peers-core for the new group
297
- await rpcServerCalls
298
- .addOrUpdatePackage(peersCorePackageId, { dataContextId: groupId })
299
- .catch((err: unknown) => {
300
- console.error("Error auto-installing peers-core for group:", err);
301
- });
295
+ // Auto-install peers-core for the new group (copy from another context that
296
+ // already has it, else fall back to the remote updateUrl / bundle).
297
+ await rpcServerCalls.seedBundledPeersCore(groupId).catch((err: unknown) => {
298
+ console.error("Error auto-installing peers-core for group:", err);
299
+ });
302
300
 
303
301
  // Notify parent
304
302
  onGroupCreated(newGroup.groupId);
@@ -86,7 +86,8 @@ export const PackageDetails = (props: IProps) => {
86
86
  key={pkg.packageId}
87
87
  doc={pkg}
88
88
  onClick={async () => {
89
- await pkg.save();
89
+ await Packages().signAndSave(pkg.toJS());
90
+ pkg.q(0);
90
91
  }}
91
92
  addActions={[...addActions]}
92
93
  />
@@ -152,6 +152,23 @@ export const PackageInfo = (props: { pkg: IDoc<IPackage> }) => {
152
152
  </div>
153
153
  ) : null}
154
154
 
155
+ <div className="mt-2">
156
+ <small>
157
+ Update URL:
158
+ <small>
159
+ <Tooltip
160
+ markdownContent={`Base URL for remote package updates. Admin devices poll **<updateUrl>/latest-<tag>.json** on startup (for example **latest-stable.json**). Signed artifacts must be published to this host separately — for example via the publish-package tool or the peers-core full-release pipeline.`}
161
+ />
162
+ </small>
163
+ </small>
164
+ <Input
165
+ value={pkg.qs.updateUrl}
166
+ className="form-control mb-3 p-0 ps-2"
167
+ placeholder="https://example.com/my-package"
168
+ title="Update URL"
169
+ />
170
+ </div>
171
+
155
172
  <div className="mt-2">
156
173
  <hr />
157
174
  <small>
@@ -126,10 +126,12 @@ const ProfileSection: React.FC = () => {
126
126
 
127
127
  const handleSave = async () => {
128
128
  try {
129
- // Save user profile
130
- if (me) {
129
+ // Save user profile (only when it actually changed). Pass me.toJS() — the
130
+ // raw doc's fields are non-enumerable getters that get dropped when the
131
+ // signAndSave call is serialized to JSON over the socket to the server.
132
+ if (me?.q()) {
131
133
  const userContext = await getUserContext();
132
- await Users(userContext.userDataContext).signAndSave(me);
134
+ await Users(userContext.userDataContext).signAndSave(me.toJS());
133
135
  me.q(0); // Reset change counter
134
136
  }
135
137
 
@@ -4,7 +4,6 @@ import {
4
4
  newid,
5
5
  newKeys,
6
6
  openMessageWithPublicKey,
7
- peersCorePackageId,
8
7
  rpcServerCalls,
9
8
  signMessageWithSecretKey,
10
9
  } from "@peers-app/peers-sdk";
@@ -36,16 +35,10 @@ export const SetupUser = () => {
36
35
  const keys = newKeys();
37
36
  const _userId = newid();
38
37
 
39
- // Call setUserIdAndSecretKey
38
+ // Call setUserIdAndSecretKey. This triggers device init, which installs
39
+ // peers-core into the personal context (S3-first, bundle fallback).
40
40
  await rpcServerCalls.setUserIdAndSecretKey(_userId, keys.secretKey);
41
41
 
42
- // Auto-install peers-core for the new user
43
- await rpcServerCalls
44
- .addOrUpdatePackage(peersCorePackageId, { dataContextId: _userId })
45
- .catch((err: unknown) => {
46
- console.error("Error auto-installing peers-core:", err);
47
- });
48
-
49
42
  // Success - reload the app (peers-services registration runs after Welcome modal)
50
43
  window.location.reload();
51
44
  } catch (err) {