@flighthq/share 0.5.1-next.1069.554a2ac → 0.5.1-next.1201.9b49dee
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 +2 -2
- package/dist/share.d.ts +8 -8
- package/dist/share.d.ts.map +1 -1
- package/dist/share.js +16 -15
- package/dist/share.js.map +1 -1
- package/package.json +4 -4
- package/src/share.test.ts +29 -27
- package/src/shareExplicit.test.ts +8 -5
package/README.md
CHANGED
|
@@ -13,5 +13,5 @@ Import the supported application-facing API from `@flighthq/share`. The `@flight
|
|
|
13
13
|
This package is part of the locked-version Flight SDK graph. Applications may instead install and import `@flighthq/sdk` when package-level tree shaking is sufficient.
|
|
14
14
|
|
|
15
15
|
- [Flight project](https://github.com/flighthq/flight)
|
|
16
|
-
- [Source for @flighthq/share@0.5.1-next.
|
|
17
|
-
- [License](https://github.com/flighthq/flight/blob/
|
|
16
|
+
- [Source for @flighthq/share@0.5.1-next.1201.9b49dee](https://github.com/flighthq/flight/tree/9b49dee3f22f6b2838c3d237edcc77bca65734f2/packages/share)
|
|
17
|
+
- [License](https://github.com/flighthq/flight/blob/9b49dee3f22f6b2838c3d237edcc77bca65734f2/LICENSE.md)
|
package/dist/share.d.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import type { EntityConstruction,
|
|
1
|
+
import type { EntityConstruction, HostShareContentProvider, HostShareFilesProvider, ShareContent, ShareFile, ShareResult, ShareSignals } from '@flighthq/types/contract';
|
|
2
2
|
export declare function attachShareSignals(signals: ShareSignals): void;
|
|
3
|
-
export declare function canShareContent(
|
|
4
|
-
export declare function canShareFiles(
|
|
3
|
+
export declare function canShareContent(hostShareContent: Readonly<HostShareContentProvider>, content: Readonly<ShareContent>): boolean;
|
|
4
|
+
export declare function canShareFiles(hostShareFiles: Readonly<HostShareFilesProvider>, files: readonly ShareFile[]): boolean;
|
|
5
5
|
export declare function detachShareSignals(signals: ShareSignals): void;
|
|
6
6
|
export declare function disposeShareSignals(signals: ShareSignals): void;
|
|
7
7
|
export declare function enableShareSignals(): ShareSignals;
|
|
8
8
|
export declare function hasShareContentFields(content: Readonly<ShareContent>): boolean;
|
|
9
9
|
export declare function initializeShareSignals(out: EntityConstruction<ShareSignals>): void;
|
|
10
10
|
export declare function isShareFileValid(file: Readonly<ShareFile>): boolean;
|
|
11
|
-
export declare function shareContent(
|
|
12
|
-
export declare function shareContentWithResult(
|
|
13
|
-
export declare function shareFiles(
|
|
14
|
-
export declare function shareText(
|
|
15
|
-
export declare function shareUrl(
|
|
11
|
+
export declare function shareContent(hostShareContent: Readonly<HostShareContentProvider>, content: Readonly<ShareContent>): Promise<boolean>;
|
|
12
|
+
export declare function shareContentWithResult(hostShareContent: Readonly<HostShareContentProvider>, content: Readonly<ShareContent>): Promise<ShareResult>;
|
|
13
|
+
export declare function shareFiles(hostShareFiles: Readonly<HostShareFilesProvider>, files: readonly ShareFile[]): Promise<boolean>;
|
|
14
|
+
export declare function shareText(hostShareContent: Readonly<HostShareContentProvider>, text: string): Promise<boolean>;
|
|
15
|
+
export declare function shareUrl(hostShareContent: Readonly<HostShareContentProvider>, url: string): Promise<boolean>;
|
|
16
16
|
//# sourceMappingURL=share.d.ts.map
|
package/dist/share.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"share.d.ts","sourceRoot":"","sources":["../src/share.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,kBAAkB,EAClB,
|
|
1
|
+
{"version":3,"file":"share.d.ts","sourceRoot":"","sources":["../src/share.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,kBAAkB,EAClB,wBAAwB,EACxB,sBAAsB,EACtB,YAAY,EACZ,SAAS,EAET,WAAW,EACX,YAAY,EACb,MAAM,0BAA0B,CAAC;AAElC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAE9D;AAKD,wBAAgB,eAAe,CAC7B,gBAAgB,EAAE,QAAQ,CAAC,wBAAwB,CAAC,EACpD,OAAO,EAAE,QAAQ,CAAC,YAAY,CAAC,GAC9B,OAAO,CAET;AAED,wBAAgB,aAAa,CAAC,cAAc,EAAE,QAAQ,CAAC,sBAAsB,CAAC,EAAE,KAAK,EAAE,SAAS,SAAS,EAAE,GAAG,OAAO,CAGpH;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAE9D;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAG/D;AAED,wBAAgB,kBAAkB,IAAI,YAAY,CAIjD;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,QAAQ,CAAC,YAAY,CAAC,GAAG,OAAO,CAK9E;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,kBAAkB,CAAC,YAAY,CAAC,GAAG,IAAI,CAElF;AAKD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,QAAQ,CAAC,SAAS,CAAC,GAAG,OAAO,CAEnE;AAED,wBAAgB,YAAY,CAC1B,gBAAgB,EAAE,QAAQ,CAAC,wBAAwB,CAAC,EACpD,OAAO,EAAE,QAAQ,CAAC,YAAY,CAAC,GAC9B,OAAO,CAAC,OAAO,CAAC,CAGlB;AAED,wBAAsB,sBAAsB,CAC1C,gBAAgB,EAAE,QAAQ,CAAC,wBAAwB,CAAC,EACpD,OAAO,EAAE,QAAQ,CAAC,YAAY,CAAC,GAC9B,OAAO,CAAC,WAAW,CAAC,CAStB;AAED,wBAAgB,UAAU,CACxB,cAAc,EAAE,QAAQ,CAAC,sBAAsB,CAAC,EAChD,KAAK,EAAE,SAAS,SAAS,EAAE,GAC1B,OAAO,CAAC,OAAO,CAAC,CAIlB;AAED,wBAAgB,SAAS,CAAC,gBAAgB,EAAE,QAAQ,CAAC,wBAAwB,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAE9G;AAED,wBAAgB,QAAQ,CAAC,gBAAgB,EAAE,QAAQ,CAAC,wBAAwB,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAE5G"}
|
package/dist/share.js
CHANGED
|
@@ -4,13 +4,14 @@ export function attachShareSignals(signals) {
|
|
|
4
4
|
_attachedSignals.add(signals);
|
|
5
5
|
}
|
|
6
6
|
// This is payload validation within the content capability. Capability presence itself is expressed
|
|
7
|
-
// by
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
// by the direct HostShareContentProvider parameter, so an absent provider is a type error rather than
|
|
8
|
+
// a false probe.
|
|
9
|
+
export function canShareContent(hostShareContent, content) {
|
|
10
|
+
return hasShareContentFields(content) && hostShareContent.canShareContent(content);
|
|
10
11
|
}
|
|
11
|
-
export function canShareFiles(
|
|
12
|
+
export function canShareFiles(hostShareFiles, files) {
|
|
12
13
|
const content = filesContent(files);
|
|
13
|
-
return content !== null &&
|
|
14
|
+
return content !== null && hostShareFiles.canShareContent(content);
|
|
14
15
|
}
|
|
15
16
|
export function detachShareSignals(signals) {
|
|
16
17
|
_attachedSignals.delete(signals);
|
|
@@ -42,32 +43,32 @@ export function initializeShareSignals(out) {
|
|
|
42
43
|
export function isShareFileValid(file) {
|
|
43
44
|
return file.name !== '' && file.mimeType !== '' && file.dataUrl.startsWith('data:') && file.dataUrl.includes(',');
|
|
44
45
|
}
|
|
45
|
-
export function shareContent(
|
|
46
|
+
export function shareContent(hostShareContent, content) {
|
|
46
47
|
if (!hasShareContentFields(content))
|
|
47
48
|
return Promise.resolve(false);
|
|
48
|
-
return
|
|
49
|
+
return hostShareContent.shareContent(content);
|
|
49
50
|
}
|
|
50
|
-
export async function shareContentWithResult(
|
|
51
|
+
export async function shareContentWithResult(hostShareContent, content) {
|
|
51
52
|
if (!hasShareContentFields(content)) {
|
|
52
53
|
return { completed: false, activityType: null, dismissed: false };
|
|
53
54
|
}
|
|
54
|
-
const result = await
|
|
55
|
+
const result = await hostShareContent.shareContentWithResult(content);
|
|
55
56
|
for (const signals of _attachedSignals) {
|
|
56
57
|
emitSignal(signals.onShareResult, result);
|
|
57
58
|
}
|
|
58
59
|
return result;
|
|
59
60
|
}
|
|
60
|
-
export function shareFiles(
|
|
61
|
+
export function shareFiles(hostShareFiles, files) {
|
|
61
62
|
const content = filesContent(files);
|
|
62
63
|
if (content === null)
|
|
63
64
|
return Promise.resolve(false);
|
|
64
|
-
return
|
|
65
|
+
return hostShareFiles.shareContent(content);
|
|
65
66
|
}
|
|
66
|
-
export function shareText(
|
|
67
|
-
return shareContent(
|
|
67
|
+
export function shareText(hostShareContent, text) {
|
|
68
|
+
return shareContent(hostShareContent, { text });
|
|
68
69
|
}
|
|
69
|
-
export function shareUrl(
|
|
70
|
-
return shareContent(
|
|
70
|
+
export function shareUrl(hostShareContent, url) {
|
|
71
|
+
return shareContent(hostShareContent, { url });
|
|
71
72
|
}
|
|
72
73
|
const _attachedSignals = new Set();
|
|
73
74
|
function filesContent(files) {
|
package/dist/share.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"share.js","sourceRoot":"","sources":["../src/share.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAYnF,MAAM,UAAU,kBAAkB,CAAC,OAAqB;IACtD,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAChC,CAAC;AAED,oGAAoG;AACpG,
|
|
1
|
+
{"version":3,"file":"share.js","sourceRoot":"","sources":["../src/share.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flighthq/share",
|
|
3
|
-
"version": "0.5.1-next.
|
|
3
|
+
"version": "0.5.1-next.1201.9b49dee",
|
|
4
4
|
"author": "Joshua Granick and other contributors",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -38,9 +38,9 @@
|
|
|
38
38
|
"clean:dist": "tsx ../../scripts/clean-package-dist.ts"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@flighthq/entity": "0.5.1-next.
|
|
42
|
-
"@flighthq/signals": "0.5.1-next.
|
|
43
|
-
"@flighthq/types": "0.5.1-next.
|
|
41
|
+
"@flighthq/entity": "0.5.1-next.1201.9b49dee",
|
|
42
|
+
"@flighthq/signals": "0.5.1-next.1201.9b49dee",
|
|
43
|
+
"@flighthq/types": "0.5.1-next.1201.9b49dee"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"typescript": "^5.3.0"
|
package/src/share.test.ts
CHANGED
|
@@ -2,11 +2,9 @@ import { allocateEntity, finishEntity } from '@flighthq/entity/contract';
|
|
|
2
2
|
import { connectSignal } from '@flighthq/signals/contract';
|
|
3
3
|
import { EntityRuntimeKey } from '@flighthq/types/contract';
|
|
4
4
|
import type {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
HostShareContentProvider,
|
|
6
|
+
HostShareFilesProvider,
|
|
7
7
|
ShareContent,
|
|
8
|
-
ShareContentBackend,
|
|
9
|
-
ShareFilesBackend,
|
|
10
8
|
ShareResult,
|
|
11
9
|
} from '@flighthq/types/contract';
|
|
12
10
|
|
|
@@ -28,11 +26,13 @@ import {
|
|
|
28
26
|
shareUrl,
|
|
29
27
|
} from './share';
|
|
30
28
|
|
|
31
|
-
function contentHost(overrides: Partial<
|
|
29
|
+
function contentHost(overrides: Partial<HostShareContentProvider> = {}): {
|
|
30
|
+
readonly share: { readonly content: HostShareContentProvider };
|
|
31
|
+
} {
|
|
32
32
|
return {
|
|
33
33
|
share: {
|
|
34
34
|
content: (() => {
|
|
35
|
-
const out = allocateEntity<
|
|
35
|
+
const out = allocateEntity<HostShareContentProvider>();
|
|
36
36
|
out.canShareContent = () => true;
|
|
37
37
|
out.shareContent = async () => true;
|
|
38
38
|
out.shareContentWithResult = async () => ({ activityType: null, completed: true, dismissed: false });
|
|
@@ -43,11 +43,13 @@ function contentHost(overrides: Partial<ShareContentBackend> = {}): HasShareCont
|
|
|
43
43
|
};
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
function filesHost(overrides: Partial<
|
|
46
|
+
function filesHost(overrides: Partial<HostShareFilesProvider> = {}): {
|
|
47
|
+
readonly share: { readonly files: HostShareFilesProvider };
|
|
48
|
+
} {
|
|
47
49
|
return {
|
|
48
50
|
share: {
|
|
49
51
|
files: (() => {
|
|
50
|
-
const out = allocateEntity<
|
|
52
|
+
const out = allocateEntity<HostShareFilesProvider>();
|
|
51
53
|
out.canShareContent = () => true;
|
|
52
54
|
out.shareContent = async () => true;
|
|
53
55
|
out.shareContentWithResult = async () => ({ activityType: null, completed: true, dismissed: false });
|
|
@@ -69,7 +71,7 @@ describe('attachShareSignals', () => {
|
|
|
69
71
|
connectSignal(signals.onShareResult, listener);
|
|
70
72
|
attachShareSignals(signals);
|
|
71
73
|
|
|
72
|
-
expect(await shareContentWithResult(host, { title: 'flight' })).toEqual(result);
|
|
74
|
+
expect(await shareContentWithResult(host.share.content, { title: 'flight' })).toEqual(result);
|
|
73
75
|
expect(listener).toHaveBeenCalledWith(result);
|
|
74
76
|
detachShareSignals(signals);
|
|
75
77
|
});
|
|
@@ -79,11 +81,11 @@ describe('canShareContent', () => {
|
|
|
79
81
|
it('validates meaningful payloads through the selected content slot', () => {
|
|
80
82
|
const can = vi.fn(() => true);
|
|
81
83
|
const host = contentHost({ canShareContent: can });
|
|
82
|
-
expect(canShareContent(host, { text: 'hello' })).toBe(true);
|
|
84
|
+
expect(canShareContent(host.share.content, { text: 'hello' })).toBe(true);
|
|
83
85
|
expect(can).toHaveBeenCalledWith({ text: 'hello' });
|
|
84
86
|
|
|
85
87
|
// @ts-expect-error an empty object is not a meaningful Share content payload
|
|
86
|
-
expect(canShareContent(contentHost(), {})).toBe(false);
|
|
88
|
+
expect(canShareContent(contentHost().share.content, {})).toBe(false);
|
|
87
89
|
});
|
|
88
90
|
});
|
|
89
91
|
|
|
@@ -91,9 +93,9 @@ describe('canShareFiles', () => {
|
|
|
91
93
|
it('validates through the files slot only for valid, non-empty lists', () => {
|
|
92
94
|
const can = vi.fn(() => true);
|
|
93
95
|
const host = filesHost({ canShareContent: can });
|
|
94
|
-
expect(canShareFiles(host, [file])).toBe(true);
|
|
95
|
-
expect(canShareFiles(host, [])).toBe(false);
|
|
96
|
-
expect(canShareFiles(host, [{ ...file, dataUrl: 'data:text/plain;base64' }])).toBe(false);
|
|
96
|
+
expect(canShareFiles(host.share.files, [file])).toBe(true);
|
|
97
|
+
expect(canShareFiles(host.share.files, [])).toBe(false);
|
|
98
|
+
expect(canShareFiles(host.share.files, [{ ...file, dataUrl: 'data:text/plain;base64' }])).toBe(false);
|
|
97
99
|
expect(can).toHaveBeenCalledTimes(1);
|
|
98
100
|
});
|
|
99
101
|
});
|
|
@@ -105,7 +107,7 @@ describe('detachShareSignals', () => {
|
|
|
105
107
|
connectSignal(signals.onShareResult, listener);
|
|
106
108
|
attachShareSignals(signals);
|
|
107
109
|
detachShareSignals(signals);
|
|
108
|
-
await shareContentWithResult(contentHost(), { title: 'quiet' });
|
|
110
|
+
await shareContentWithResult(contentHost().share.content, { title: 'quiet' });
|
|
109
111
|
expect(listener).not.toHaveBeenCalled();
|
|
110
112
|
});
|
|
111
113
|
});
|
|
@@ -117,7 +119,7 @@ describe('disposeShareSignals', () => {
|
|
|
117
119
|
connectSignal(signals.onShareResult, listener);
|
|
118
120
|
attachShareSignals(signals);
|
|
119
121
|
disposeShareSignals(signals);
|
|
120
|
-
await shareContentWithResult(contentHost(), { text: 'quiet' });
|
|
122
|
+
await shareContentWithResult(contentHost().share.content, { text: 'quiet' });
|
|
121
123
|
expect(listener).not.toHaveBeenCalled();
|
|
122
124
|
});
|
|
123
125
|
});
|
|
@@ -182,8 +184,8 @@ describe('shareContent', () => {
|
|
|
182
184
|
const backend = vi.fn(async () => true);
|
|
183
185
|
const host = contentHost({ shareContent: backend });
|
|
184
186
|
const empty = { text: '' } as ShareContent;
|
|
185
|
-
expect(canShareContent(host, empty)).toBe(false);
|
|
186
|
-
expect(await shareContent(host, empty)).toBe(false);
|
|
187
|
+
expect(canShareContent(host.share.content, empty)).toBe(false);
|
|
188
|
+
expect(await shareContent(host.share.content, empty)).toBe(false);
|
|
187
189
|
expect(backend).not.toHaveBeenCalled();
|
|
188
190
|
});
|
|
189
191
|
});
|
|
@@ -192,17 +194,17 @@ describe('shareContentWithResult', () => {
|
|
|
192
194
|
it('returns a detailed provider outcome', async () => {
|
|
193
195
|
const result: ShareResult = { activityType: 'mail', completed: true, dismissed: false };
|
|
194
196
|
const host = contentHost({ shareContentWithResult: async () => result });
|
|
195
|
-
expect(await shareContentWithResult(host, { title: 'flight' })).toEqual(result);
|
|
197
|
+
expect(await shareContentWithResult(host.share.content, { title: 'flight' })).toEqual(result);
|
|
196
198
|
});
|
|
197
199
|
});
|
|
198
200
|
|
|
199
201
|
describe('shareFiles', () => {
|
|
200
202
|
it('dispatches only a valid, non-empty portable file tuple', async () => {
|
|
201
|
-
const invoke = vi.fn(async (_content: Parameters<
|
|
203
|
+
const invoke = vi.fn(async (_content: Parameters<HostShareFilesProvider['shareContent']>[0]) => true);
|
|
202
204
|
const host = filesHost({ shareContent: invoke });
|
|
203
|
-
expect(await shareFiles(host, [file])).toBe(true);
|
|
204
|
-
expect(await shareFiles(host, [])).toBe(false);
|
|
205
|
-
expect(await shareFiles(host, [{ ...file, dataUrl: 'not-a-data-url' }])).toBe(false);
|
|
205
|
+
expect(await shareFiles(host.share.files, [file])).toBe(true);
|
|
206
|
+
expect(await shareFiles(host.share.files, [])).toBe(false);
|
|
207
|
+
expect(await shareFiles(host.share.files, [{ ...file, dataUrl: 'not-a-data-url' }])).toBe(false);
|
|
206
208
|
expect(invoke).toHaveBeenCalledTimes(1);
|
|
207
209
|
expect(invoke.mock.calls[0]?.[0].files).toEqual([file]);
|
|
208
210
|
});
|
|
@@ -210,15 +212,15 @@ describe('shareFiles', () => {
|
|
|
210
212
|
|
|
211
213
|
describe('shareText', () => {
|
|
212
214
|
it('delegates text through the content slot', async () => {
|
|
213
|
-
const invoke = vi.fn(async (_content: Parameters<
|
|
214
|
-
expect(await shareText(contentHost({ shareContent: invoke }), 'hello')).toBe(true);
|
|
215
|
+
const invoke = vi.fn(async (_content: Parameters<HostShareContentProvider['shareContent']>[0]) => true);
|
|
216
|
+
expect(await shareText(contentHost({ shareContent: invoke }).share.content, 'hello')).toBe(true);
|
|
215
217
|
expect(invoke).toHaveBeenCalledWith({ text: 'hello' });
|
|
216
218
|
});
|
|
217
219
|
});
|
|
218
220
|
describe('shareUrl', () => {
|
|
219
221
|
it('delegates a URL through the content slot', async () => {
|
|
220
|
-
const invoke = vi.fn(async (_content: Parameters<
|
|
221
|
-
expect(await shareUrl(contentHost({ shareContent: invoke }), 'https://flight.dev')).toBe(true);
|
|
222
|
+
const invoke = vi.fn(async (_content: Parameters<HostShareContentProvider['shareContent']>[0]) => true);
|
|
223
|
+
expect(await shareUrl(contentHost({ shareContent: invoke }).share.content, 'https://flight.dev')).toBe(true);
|
|
222
224
|
expect(invoke).toHaveBeenCalledWith({ url: 'https://flight.dev' });
|
|
223
225
|
});
|
|
224
226
|
});
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { allocateEntity, finishEntity } from '@flighthq/entity/contract';
|
|
2
|
-
import type {
|
|
2
|
+
import type { HostShareContentProvider, ShareContent } from '@flighthq/types/contract';
|
|
3
3
|
|
|
4
4
|
import { shareText } from './share';
|
|
5
5
|
|
|
6
|
-
function createRecordingHost(
|
|
7
|
-
|
|
6
|
+
function createRecordingHost(
|
|
7
|
+
label: string,
|
|
8
|
+
calls: string[],
|
|
9
|
+
): { readonly share: { readonly content: HostShareContentProvider } } {
|
|
10
|
+
const content = allocateEntity<HostShareContentProvider>();
|
|
8
11
|
content.canShareContent = () => true;
|
|
9
12
|
content.shareContent = async (payload: Readonly<ShareContent>) => {
|
|
10
13
|
calls.push(`${label}:${payload.text ?? ''}`);
|
|
@@ -22,8 +25,8 @@ describe('explicit Share host isolation', () => {
|
|
|
22
25
|
const first = createRecordingHost('first', calls);
|
|
23
26
|
const second = createRecordingHost('second', calls);
|
|
24
27
|
|
|
25
|
-
expect(await shareText(first, 'alpha')).toBe(true);
|
|
26
|
-
expect(await shareText(second, 'beta')).toBe(true);
|
|
28
|
+
expect(await shareText(first.share.content, 'alpha')).toBe(true);
|
|
29
|
+
expect(await shareText(second.share.content, 'beta')).toBe(true);
|
|
27
30
|
expect(calls).toEqual(['first:alpha', 'second:beta']);
|
|
28
31
|
});
|
|
29
32
|
});
|