@peers-app/peers-ui 0.18.8 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +83 -0
- package/dist/screens/groups/group-list.js +1 -3
- package/dist/screens/packages/package-versions.js +17 -1
- package/dist/system-apps/index.js +1 -0
- package/dist/ui-router/routes-loader.d.ts +2 -0
- package/package.json +3 -3
- package/src/screens/groups/group-list.tsx +3 -6
- package/src/screens/packages/package-versions.tsx +20 -1
- package/src/system-apps/index.ts +1 -0
package/README.md
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# @peers-app/peers-ui
|
|
2
|
+
|
|
3
|
+
React components and hooks for building [Peers](https://peers.app) package UIs.
|
|
4
|
+
|
|
5
|
+
## What is Peers?
|
|
6
|
+
|
|
7
|
+
Peers is a local-first personal computing platform. Your data lives on your devices, syncs peer-to-peer, and is end-to-end encrypted — no servers in the middle. You own your data and your identity. Build apps with the SDK or use AI coding tools to create them; either way, the platform handles sync, encryption, and persistence automatically.
|
|
8
|
+
|
|
9
|
+
## What this package provides
|
|
10
|
+
|
|
11
|
+
### React Hooks
|
|
12
|
+
|
|
13
|
+
Hooks that bridge `@peers-app/peers-sdk` observables to React 18 with concurrent rendering support.
|
|
14
|
+
|
|
15
|
+
| Hook | Purpose |
|
|
16
|
+
|------|---------|
|
|
17
|
+
| `useObservable` | Subscribe to an observable or computed; returns `[value, setter]` |
|
|
18
|
+
| `useObservableState` | Create a component-local observable that persists across renders |
|
|
19
|
+
| `usePromise` | Resolve a promise in a component with an optional initial value |
|
|
20
|
+
| `useSubscription` | Run a side-effect whenever an observable changes |
|
|
21
|
+
| `useOnScreen` | IntersectionObserver hook for visibility detection |
|
|
22
|
+
|
|
23
|
+
### Rich Text
|
|
24
|
+
|
|
25
|
+
- **`MarkdownEditor`** — Lexical-based rich text editor with @mention support, toolbar, and markdown serialization
|
|
26
|
+
- **`MarkdownWithMentions`** — Render markdown with resolved @user and $tool mentions
|
|
27
|
+
|
|
28
|
+
### Layout
|
|
29
|
+
|
|
30
|
+
- **`TabsLayout`** — Multi-tab application shell used by the Peers desktop and PWA clients
|
|
31
|
+
- **`SortableList`** — Drag-and-drop list powered by SortableJS
|
|
32
|
+
- **`InverseLazyList`** — Bottom-anchored lazy-loading list for chat-style UIs
|
|
33
|
+
- **`Tabs`** / **`ScreenTabBody`** — Tab strip and content container
|
|
34
|
+
|
|
35
|
+
### Communication
|
|
36
|
+
|
|
37
|
+
- **`ChatOverlay`** — Floating chat panel for AI assistant conversations
|
|
38
|
+
- **`VoiceIndicator`** — Visual indicator for active voice sessions
|
|
39
|
+
|
|
40
|
+
### Tab Management
|
|
41
|
+
|
|
42
|
+
| Export | Purpose |
|
|
43
|
+
|--------|---------|
|
|
44
|
+
| `goToTabPath` | Navigate to a path within the Peers tab system |
|
|
45
|
+
| `activeTabId` | Observable of the currently active tab ID |
|
|
46
|
+
| `activeTabs` | Observable of all open tabs |
|
|
47
|
+
| `closeCurrentTab` | Close the active tab |
|
|
48
|
+
| `updateActiveTabTitle` | Set the title of the active tab |
|
|
49
|
+
| `TabState` | Tab state management class |
|
|
50
|
+
| `mainContentPath` | Hash-synced route observable |
|
|
51
|
+
|
|
52
|
+
## Peer Dependencies
|
|
53
|
+
|
|
54
|
+
```json
|
|
55
|
+
{
|
|
56
|
+
"@peers-app/peers-sdk": "^0.18.8",
|
|
57
|
+
"bootstrap": "^5.3.3",
|
|
58
|
+
"react": "^18.0.0",
|
|
59
|
+
"react-dom": "^18.0.0"
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Quick Start
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
npm install @peers-app/peers-ui
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
The fastest way to build a Peers package with a UI is to start from the template:
|
|
70
|
+
|
|
71
|
+
**[peers-package-template](https://github.com/peers-app/peers-package-template)** — scaffold, build, and install a custom package into the Peers runtime.
|
|
72
|
+
|
|
73
|
+
Package UI bundles receive `PeersUI` as a webpack external, so you can import hooks and components without bundling them into your package.
|
|
74
|
+
|
|
75
|
+
## Links
|
|
76
|
+
|
|
77
|
+
- [peers.app](https://peers.app) — try Peers in your browser or download the desktop app
|
|
78
|
+
- [Documentation](https://peers-app.github.io) — architecture, package development, and API reference
|
|
79
|
+
- [GitHub](https://github.com/peers-app) — source repositories and package template
|
|
80
|
+
|
|
81
|
+
## License
|
|
82
|
+
|
|
83
|
+
MIT
|
|
@@ -111,9 +111,7 @@ function GroupList() {
|
|
|
111
111
|
});
|
|
112
112
|
await (0, peers_sdk_1.Groups)(groupDataContext).signAndSave(group);
|
|
113
113
|
// Auto-install peers-core for the new group
|
|
114
|
-
await peers_sdk_1.rpcServerCalls
|
|
115
|
-
.addOrUpdatePackage(peers_sdk_1.peersCorePackageId, { dataContextId: groupId })
|
|
116
|
-
.catch((err) => {
|
|
114
|
+
await peers_sdk_1.rpcServerCalls.seedBundledPeersCore(groupId).catch((err) => {
|
|
117
115
|
console.error("Error auto-installing peers-core for group:", err);
|
|
118
116
|
});
|
|
119
117
|
(0, globals_1.mainContentPath)(`groups/${group.groupId}`);
|
|
@@ -125,7 +125,23 @@ const PackageVersionsList = (props) => {
|
|
|
125
125
|
signature: "",
|
|
126
126
|
});
|
|
127
127
|
const pvHash = (0, peers_sdk_1.computePackageVersionHash)(pv.version, newTag, pv.packageBundleFileHash, pv.routesBundleFileHash, pv.uiBundleFileHash);
|
|
128
|
-
const updated = {
|
|
128
|
+
const updated = {
|
|
129
|
+
...pv,
|
|
130
|
+
versionTag: newTag,
|
|
131
|
+
packageVersionHash: pvHash,
|
|
132
|
+
history,
|
|
133
|
+
};
|
|
134
|
+
// Auto-sign with package author key if available (server-side, key never exposed)
|
|
135
|
+
const authorSig = await peers_sdk_1.rpcServerCalls.signPackageAuthorVersion({
|
|
136
|
+
packageId: updated.packageId,
|
|
137
|
+
packageVersionId: updated.packageVersionId,
|
|
138
|
+
version: updated.version,
|
|
139
|
+
versionTag: newTag,
|
|
140
|
+
packageBundleFileHash: updated.packageBundleFileHash,
|
|
141
|
+
routesBundleFileHash: updated.routesBundleFileHash,
|
|
142
|
+
uiBundleFileHash: updated.uiBundleFileHash,
|
|
143
|
+
});
|
|
144
|
+
updated.packageAuthorSignature = authorSig;
|
|
129
145
|
await (0, peers_sdk_1.PackageVersions)().signAndSave(updated, { saveAsSnapshot: true });
|
|
130
146
|
refreshKey(refreshKey() + 1);
|
|
131
147
|
}
|
|
@@ -5,6 +5,7 @@ export declare const allPackages: import("@peers-app/peers-sdk").Observable<{
|
|
|
5
5
|
signature: string;
|
|
6
6
|
packageId: string;
|
|
7
7
|
createdBy: string;
|
|
8
|
+
publishPublicKey: string;
|
|
8
9
|
disabled?: boolean | undefined;
|
|
9
10
|
appNavs?: {
|
|
10
11
|
name: string;
|
|
@@ -16,5 +17,6 @@ export declare const allPackages: import("@peers-app/peers-sdk").Observable<{
|
|
|
16
17
|
activePackageVersionId?: string | undefined;
|
|
17
18
|
versionFollowRange?: "pinned" | "patch" | "minor" | "latest" | undefined;
|
|
18
19
|
followVersionTags?: string | undefined;
|
|
20
|
+
updateUrl?: string | undefined;
|
|
19
21
|
}[]>;
|
|
20
22
|
export declare const loadAllRoutes: () => Promise<true | undefined>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@peers-app/peers-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.0",
|
|
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.
|
|
31
|
+
"@peers-app/peers-sdk": "^0.19.0",
|
|
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.
|
|
42
|
+
"@peers-app/peers-sdk": "0.19.0",
|
|
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",
|
|
@@ -7,7 +7,6 @@ import {
|
|
|
7
7
|
newid,
|
|
8
8
|
newKeys,
|
|
9
9
|
observable,
|
|
10
|
-
peersCorePackageId,
|
|
11
10
|
rpcServerCalls,
|
|
12
11
|
setUserTrustLevel,
|
|
13
12
|
TrustLevel,
|
|
@@ -132,11 +131,9 @@ export function GroupList() {
|
|
|
132
131
|
await Groups(groupDataContext).signAndSave(group);
|
|
133
132
|
|
|
134
133
|
// Auto-install peers-core for the new group
|
|
135
|
-
await rpcServerCalls
|
|
136
|
-
.
|
|
137
|
-
|
|
138
|
-
console.error("Error auto-installing peers-core for group:", err);
|
|
139
|
-
});
|
|
134
|
+
await rpcServerCalls.seedBundledPeersCore(groupId).catch((err: unknown) => {
|
|
135
|
+
console.error("Error auto-installing peers-core for group:", err);
|
|
136
|
+
});
|
|
140
137
|
|
|
141
138
|
mainContentPath(`groups/${group.groupId}`);
|
|
142
139
|
return group;
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
Packages,
|
|
9
9
|
PackageVersions,
|
|
10
10
|
packagePrefsVar,
|
|
11
|
+
rpcServerCalls,
|
|
11
12
|
Users,
|
|
12
13
|
updatePackagePrefs,
|
|
13
14
|
} from "@peers-app/peers-sdk";
|
|
@@ -136,7 +137,25 @@ export const PackageVersionsList = (props: { pkg: IDoc<IPackage> }) => {
|
|
|
136
137
|
pv.routesBundleFileHash,
|
|
137
138
|
pv.uiBundleFileHash,
|
|
138
139
|
);
|
|
139
|
-
const updated = {
|
|
140
|
+
const updated: IPackageVersion = {
|
|
141
|
+
...pv,
|
|
142
|
+
versionTag: newTag,
|
|
143
|
+
packageVersionHash: pvHash,
|
|
144
|
+
history,
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
// Auto-sign with package author key if available (server-side, key never exposed)
|
|
148
|
+
const authorSig = await rpcServerCalls.signPackageAuthorVersion({
|
|
149
|
+
packageId: updated.packageId,
|
|
150
|
+
packageVersionId: updated.packageVersionId,
|
|
151
|
+
version: updated.version,
|
|
152
|
+
versionTag: newTag,
|
|
153
|
+
packageBundleFileHash: updated.packageBundleFileHash,
|
|
154
|
+
routesBundleFileHash: updated.routesBundleFileHash,
|
|
155
|
+
uiBundleFileHash: updated.uiBundleFileHash,
|
|
156
|
+
});
|
|
157
|
+
updated.packageAuthorSignature = authorSig;
|
|
158
|
+
|
|
140
159
|
await PackageVersions().signAndSave(updated, { saveAsSnapshot: true });
|
|
141
160
|
refreshKey(refreshKey() + 1);
|
|
142
161
|
} catch (err: unknown) {
|