@peers-app/peers-ui 0.29.1 → 0.29.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/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.js +1 -0
- package/dist/hooks/use-file-url.d.ts +23 -0
- package/dist/hooks/use-file-url.js +52 -0
- package/dist/ui-router/bundle-files.d.ts +8 -0
- package/dist/ui-router/bundle-files.js +28 -0
- package/dist/ui-router/routes-loader.js +3 -2
- package/dist/ui-router/ui-loader.js +2 -1
- package/package.json +3 -3
package/dist/hooks/index.d.ts
CHANGED
package/dist/hooks/index.js
CHANGED
|
@@ -15,6 +15,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
// `use-host-contract` stays internal: its screens import it by path.
|
|
18
|
+
__exportStar(require("./use-file-url"), exports);
|
|
18
19
|
__exportStar(require("./use-observable"), exports);
|
|
19
20
|
__exportStar(require("./use-observable-state"), exports);
|
|
20
21
|
__exportStar(require("./use-on-screen"), exports);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** What {@link useFileUrl} returns. */
|
|
2
|
+
export interface IUseFileUrlResult {
|
|
3
|
+
/** An object URL for the file, such as an `<img src>`. Undefined until it's read. */
|
|
4
|
+
url: string | undefined;
|
|
5
|
+
/** True while the file is being read. */
|
|
6
|
+
loading: boolean;
|
|
7
|
+
/** Why the file couldn't be read: not found, or not on any connected device. */
|
|
8
|
+
error: Error | undefined;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Read a file saved with System Files and give a URL for it, for an image or a download link.
|
|
12
|
+
*
|
|
13
|
+
* ```tsx
|
|
14
|
+
* const avatar = useFileUrl(member.imageFileId);
|
|
15
|
+
* {avatar.url ? <img src={avatar.url} alt="" /> : <Initials />}
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* Reads through `hostContract(SystemFiles)` in the screen's data context, the active group.
|
|
19
|
+
* The URL is revoked when the file id changes or the component unmounts, so don't keep it.
|
|
20
|
+
*
|
|
21
|
+
* @param fileId - The file's id; nothing is read while it's undefined.
|
|
22
|
+
*/
|
|
23
|
+
export declare function useFileUrl(fileId: string | undefined): IUseFileUrlResult;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useFileUrl = useFileUrl;
|
|
4
|
+
const peers_sdk_1 = require("@peers-app/peers-sdk");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
/**
|
|
7
|
+
* Read a file saved with System Files and give a URL for it, for an image or a download link.
|
|
8
|
+
*
|
|
9
|
+
* ```tsx
|
|
10
|
+
* const avatar = useFileUrl(member.imageFileId);
|
|
11
|
+
* {avatar.url ? <img src={avatar.url} alt="" /> : <Initials />}
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* Reads through `hostContract(SystemFiles)` in the screen's data context, the active group.
|
|
15
|
+
* The URL is revoked when the file id changes or the component unmounts, so don't keep it.
|
|
16
|
+
*
|
|
17
|
+
* @param fileId - The file's id; nothing is read while it's undefined.
|
|
18
|
+
*/
|
|
19
|
+
function useFileUrl(fileId) {
|
|
20
|
+
const [state, setState] = (0, react_1.useState)({
|
|
21
|
+
url: undefined,
|
|
22
|
+
loading: !!fileId,
|
|
23
|
+
error: undefined,
|
|
24
|
+
});
|
|
25
|
+
(0, react_1.useEffect)(() => {
|
|
26
|
+
if (!fileId) {
|
|
27
|
+
setState({ url: undefined, loading: false, error: undefined });
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
let ended = false;
|
|
31
|
+
let url;
|
|
32
|
+
setState({ url: undefined, loading: true, error: undefined });
|
|
33
|
+
const files = (0, peers_sdk_1.hostContract)(peers_sdk_1.SystemFiles);
|
|
34
|
+
(0, peers_sdk_1.readWholeFile)((input) => files.tools.read(input), fileId).then(({ bytes, mimeType }) => {
|
|
35
|
+
if (ended)
|
|
36
|
+
return;
|
|
37
|
+
url = URL.createObjectURL(new Blob([bytes], mimeType ? { type: mimeType } : undefined));
|
|
38
|
+
setState({ url, loading: false, error: undefined });
|
|
39
|
+
}, (error) => {
|
|
40
|
+
if (ended)
|
|
41
|
+
return;
|
|
42
|
+
const reason = error instanceof Error ? error : new Error(String(error));
|
|
43
|
+
setState({ url: undefined, loading: false, error: reason });
|
|
44
|
+
});
|
|
45
|
+
return () => {
|
|
46
|
+
ended = true;
|
|
47
|
+
if (url)
|
|
48
|
+
URL.revokeObjectURL(url);
|
|
49
|
+
};
|
|
50
|
+
}, [fileId]);
|
|
51
|
+
return state;
|
|
52
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read a package's UI or routes bundle as text, through System Files in the context its
|
|
3
|
+
* version is installed in.
|
|
4
|
+
*
|
|
5
|
+
* @param dataContextId - Context of the selected package version.
|
|
6
|
+
* @param fileId - The bundle's file id.
|
|
7
|
+
*/
|
|
8
|
+
export declare function readBundleText(dataContextId: string, fileId: string): Promise<string>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.readBundleText = readBundleText;
|
|
4
|
+
const peers_sdk_1 = require("@peers-app/peers-sdk");
|
|
5
|
+
const clients = new Map();
|
|
6
|
+
/** System Files on the local host, scoped to one data context; one client per context. */
|
|
7
|
+
function filesIn(dataContextId) {
|
|
8
|
+
let client = clients.get(dataContextId);
|
|
9
|
+
if (!client) {
|
|
10
|
+
client = (0, peers_sdk_1.hostContract)(peers_sdk_1.SystemFiles, { dataContextId: async () => dataContextId });
|
|
11
|
+
clients.set(dataContextId, client);
|
|
12
|
+
}
|
|
13
|
+
return client;
|
|
14
|
+
}
|
|
15
|
+
// Keep a leading BOM, as Buffer's UTF-8 decoding did, so bundle integrity hashes still match.
|
|
16
|
+
const decoder = new TextDecoder("utf-8", { ignoreBOM: true });
|
|
17
|
+
/**
|
|
18
|
+
* Read a package's UI or routes bundle as text, through System Files in the context its
|
|
19
|
+
* version is installed in.
|
|
20
|
+
*
|
|
21
|
+
* @param dataContextId - Context of the selected package version.
|
|
22
|
+
* @param fileId - The bundle's file id.
|
|
23
|
+
*/
|
|
24
|
+
async function readBundleText(dataContextId, fileId) {
|
|
25
|
+
const files = filesIn(dataContextId);
|
|
26
|
+
const { bytes } = await (0, peers_sdk_1.readWholeFile)((input) => files.tools.read(input), fileId);
|
|
27
|
+
return decoder.decode(bytes);
|
|
28
|
+
}
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.loadAllRoutes = exports.allPackages = void 0;
|
|
4
4
|
const peers_sdk_1 = require("@peers-app/peers-sdk");
|
|
5
5
|
require("../ui-defaults");
|
|
6
|
+
const bundle_files_1 = require("./bundle-files");
|
|
6
7
|
const runnable_version_1 = require("./runnable-version");
|
|
7
8
|
/** Packages with authorized navigation metadata available in the current context. */
|
|
8
9
|
exports.allPackages = (0, peers_sdk_1.observable)([]);
|
|
@@ -102,8 +103,8 @@ function loadRoutesBundle(pkg, forceRefresh) {
|
|
|
102
103
|
const selected = await (0, runnable_version_1.resolveRunnableVersion)(pkg);
|
|
103
104
|
const routesBundleFileId = selected?.pv.routesBundleFileId;
|
|
104
105
|
let bundleCode = "";
|
|
105
|
-
if (routesBundleFileId) {
|
|
106
|
-
bundleCode = await
|
|
106
|
+
if (selected && routesBundleFileId) {
|
|
107
|
+
bundleCode = await (0, bundle_files_1.readBundleText)(selected.dataContext.dataContextId, routesBundleFileId);
|
|
107
108
|
}
|
|
108
109
|
if (bundleCode) {
|
|
109
110
|
if (selected?.dataContext.groupId)
|
|
@@ -43,6 +43,7 @@ const loading_indicator_1 = require("../components/loading-indicator");
|
|
|
43
43
|
const globals_1 = require("../globals");
|
|
44
44
|
const hooks_1 = require("../hooks");
|
|
45
45
|
require("../ui-defaults");
|
|
46
|
+
const bundle_files_1 = require("./bundle-files");
|
|
46
47
|
const routes_loader_1 = require("./routes-loader");
|
|
47
48
|
const runnable_version_1 = require("./runnable-version");
|
|
48
49
|
const peersUIs = {};
|
|
@@ -194,7 +195,7 @@ function loadUIBundle(pkg, forceRefresh) {
|
|
|
194
195
|
if (!selected || !uiBundleFileId) {
|
|
195
196
|
return;
|
|
196
197
|
}
|
|
197
|
-
const bundleCode = await
|
|
198
|
+
const bundleCode = await (0, bundle_files_1.readBundleText)(selected.dataContext.dataContextId, uiBundleFileId);
|
|
198
199
|
if (bundleCode) {
|
|
199
200
|
if (selected.dataContext.groupId)
|
|
200
201
|
(0, peers_sdk_1.assertPackageBundleIntegrity)(selected.pv, "ui", bundleCode);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@peers-app/peers-ui",
|
|
3
|
-
"version": "0.29.
|
|
3
|
+
"version": "0.29.2",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/peers-app/peers-ui.git"
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"lint:fix": "biome check --write ."
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
|
-
"@peers-app/peers-sdk": "^0.29.
|
|
39
|
+
"@peers-app/peers-sdk": "^0.29.2",
|
|
40
40
|
"bootstrap": "^5.3.3",
|
|
41
41
|
"react": "^18.0.0",
|
|
42
42
|
"react-dom": "^18.0.0"
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"@babel/preset-react": "^7.24.1",
|
|
48
48
|
"@babel/preset-typescript": "^7.27.1",
|
|
49
49
|
"@biomejs/biome": "2.3.11",
|
|
50
|
-
"@peers-app/peers-sdk": "0.29.
|
|
50
|
+
"@peers-app/peers-sdk": "0.29.2",
|
|
51
51
|
"@testing-library/dom": "^10.4.0",
|
|
52
52
|
"@testing-library/jest-dom": "^6.6.3",
|
|
53
53
|
"@testing-library/react": "^16.3.0",
|