@flighthq/share 0.3.0-next.906.07cea63 → 0.3.1-next.209.43ef1bc
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/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/share.d.ts +2 -1
- package/dist/share.d.ts.map +1 -1
- package/dist/share.js +24 -12
- package/dist/share.js.map +1 -1
- package/package.json +5 -3
- package/src/share.test.ts +70 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { attachShareSignals, canShareContent, detachShareSignals, disposeShareSignals, enableShareSignals, hasShareContentFields, isShareAvailable, shareContent, shareContentWithResult, shareText, shareUrl, } from './contract';
|
|
1
|
+
export { attachShareSignals, canShareContent, detachShareSignals, disposeShareSignals, enableShareSignals, hasShareContentFields, isShareAvailable, shareContent, shareContentWithResult, shareFiles, shareText, shareUrl, } from './contract';
|
|
2
2
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,EACrB,gBAAgB,EAChB,YAAY,EACZ,sBAAsB,EACtB,SAAS,EACT,QAAQ,GACT,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,EACrB,gBAAgB,EAChB,YAAY,EACZ,sBAAsB,EACtB,UAAU,EACV,SAAS,EACT,QAAQ,GACT,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { attachShareSignals, canShareContent, detachShareSignals, disposeShareSignals, enableShareSignals, hasShareContentFields, isShareAvailable, shareContent, shareContentWithResult, shareText, shareUrl, } from './contract';
|
|
1
|
+
export { attachShareSignals, canShareContent, detachShareSignals, disposeShareSignals, enableShareSignals, hasShareContentFields, isShareAvailable, shareContent, shareContentWithResult, shareFiles, shareText, shareUrl, } from './contract';
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,EACrB,gBAAgB,EAChB,YAAY,EACZ,sBAAsB,EACtB,SAAS,EACT,QAAQ,GACT,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,EACrB,gBAAgB,EAChB,YAAY,EACZ,sBAAsB,EACtB,UAAU,EACV,SAAS,EACT,QAAQ,GACT,MAAM,YAAY,CAAC"}
|
package/dist/share.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ShareBackend, ShareContent, ShareOptions, ShareResult, ShareSignals } from '@flighthq/types/contract';
|
|
1
|
+
import type { ShareBackend, ShareContent, ShareFile, ShareOptions, ShareResult, ShareSignals } from '@flighthq/types/contract';
|
|
2
2
|
export declare function attachShareSignals(signals: ShareSignals): void;
|
|
3
3
|
export declare function canShareContent(content: Readonly<ShareContent>): boolean;
|
|
4
4
|
export declare function createWebShareBackend(): ShareBackend;
|
|
@@ -11,6 +11,7 @@ export declare function isShareAvailable(): boolean;
|
|
|
11
11
|
export declare function setShareBackend(backend: ShareBackend | null): void;
|
|
12
12
|
export declare function shareContent(content: Readonly<ShareContent>, options?: Readonly<ShareOptions>): Promise<boolean>;
|
|
13
13
|
export declare function shareContentWithResult(content: Readonly<ShareContent>, options?: Readonly<ShareOptions>): Promise<ShareResult>;
|
|
14
|
+
export declare function shareFiles(files: readonly ShareFile[], options?: Readonly<ShareOptions>): Promise<boolean>;
|
|
14
15
|
export declare function shareText(text: string, options?: Readonly<ShareOptions>): Promise<boolean>;
|
|
15
16
|
export declare function shareUrl(url: string, options?: Readonly<ShareOptions>): Promise<boolean>;
|
|
16
17
|
//# 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":"AACA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"share.d.ts","sourceRoot":"","sources":["../src/share.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,YAAY,EACZ,YAAY,EACZ,SAAS,EACT,YAAY,EACZ,WAAW,EACX,YAAY,EACb,MAAM,0BAA0B,CAAC;AASlC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAE9D;AAMD,wBAAgB,eAAe,CAAC,OAAO,EAAE,QAAQ,CAAC,YAAY,CAAC,GAAG,OAAO,CAExE;AAQD,wBAAgB,qBAAqB,IAAI,YAAY,CA4CpD;AAGD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAE9D;AAID,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAE/D;AAID,wBAAgB,kBAAkB,IAAI,YAAY,CAIjD;AAGD,wBAAgB,eAAe,IAAI,YAAY,CAG9C;AAMD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,QAAQ,CAAC,YAAY,CAAC,GAAG,OAAO,CAM9E;AAKD,wBAAgB,gBAAgB,IAAI,OAAO,CAE1C;AAGD,wBAAgB,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,GAAG,IAAI,CAElE;AAOD,wBAAgB,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAGhH;AAMD,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,QAAQ,CAAC,YAAY,CAAC,EAC/B,OAAO,CAAC,EAAE,QAAQ,CAAC,YAAY,CAAC,GAC/B,OAAO,CAAC,WAAW,CAAC,CAStB;AAMD,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAE1G;AAGD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAE1F;AAGD,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAExF"}
|
package/dist/share.js
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import { createSignal, emitSignal } from '@flighthq/signals/contract';
|
|
2
|
-
// Attaches `signals` to receive share result events emitted by shareContentWithResult calls.
|
|
3
|
-
//
|
|
4
|
-
// disposeShareSignals.
|
|
2
|
+
// Attaches `signals` to receive share result events emitted by shareContentWithResult calls.
|
|
3
|
+
// Idempotent by construction — the attached groups are a set, so attaching twice delivers once.
|
|
4
|
+
// Pair with detachShareSignals / disposeShareSignals.
|
|
5
5
|
//
|
|
6
6
|
// Note: shareContent (the boolean convenience wrapper) does NOT emit signals — only
|
|
7
7
|
// shareContentWithResult emits onShareResult. If you need signals on every share, use
|
|
8
8
|
// shareContentWithResult directly.
|
|
9
9
|
export function attachShareSignals(signals) {
|
|
10
|
-
|
|
11
|
-
_signalListeners.set(signals, true);
|
|
10
|
+
_attachedSignals.add(signals);
|
|
12
11
|
}
|
|
13
12
|
// True when the active backend can share the given content. Returns false when sharing is
|
|
14
13
|
// unavailable or the content is not shareable by this platform (e.g. a MIME type not accepted by
|
|
@@ -71,7 +70,7 @@ export function createWebShareBackend() {
|
|
|
71
70
|
}
|
|
72
71
|
// Stops delivery to `signals` and forgets its subscription. Safe to call when not attached.
|
|
73
72
|
export function detachShareSignals(signals) {
|
|
74
|
-
|
|
73
|
+
_attachedSignals.delete(signals);
|
|
75
74
|
}
|
|
76
75
|
// Releases `signals` for garbage collection by detaching its subscription. The signals remain plain
|
|
77
76
|
// GC-managed memory afterward.
|
|
@@ -135,13 +134,18 @@ export async function shareContentWithResult(content, options) {
|
|
|
135
134
|
return { completed: false, activityType: null, dismissed: false };
|
|
136
135
|
}
|
|
137
136
|
const result = await getShareBackend().shareWithResult(content, options);
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
emitSignal(signals.onShareResult, result);
|
|
141
|
-
}
|
|
137
|
+
for (const signals of _attachedSignals) {
|
|
138
|
+
emitSignal(signals.onShareResult, result);
|
|
142
139
|
}
|
|
143
140
|
return result;
|
|
144
141
|
}
|
|
142
|
+
// Opens the share sheet with a file payload. A convenience wrapper over shareContent, completing the
|
|
143
|
+
// trio with shareText / shareUrl — files are the third thing the Web Share Level 2 payload carries,
|
|
144
|
+
// and leaving it out meant the one payload kind that needs a descriptor was also the one with no
|
|
145
|
+
// shorthand. An empty array resolves false, like any other empty payload.
|
|
146
|
+
export function shareFiles(files, options) {
|
|
147
|
+
return shareContent({ files }, options);
|
|
148
|
+
}
|
|
145
149
|
// Opens the share sheet with a plain text payload. A convenience wrapper over shareContent.
|
|
146
150
|
export function shareText(text, options) {
|
|
147
151
|
return shareContent({ text }, options);
|
|
@@ -151,8 +155,9 @@ export function shareUrl(url, options) {
|
|
|
151
155
|
return shareContent({ url }, options);
|
|
152
156
|
}
|
|
153
157
|
let _backend = null;
|
|
154
|
-
//
|
|
155
|
-
|
|
158
|
+
// The signals groups attached via attachShareSignals. A set, not a map to a dummy value: membership
|
|
159
|
+
// is the whole state, and expressing it as a set is what makes attach idempotent without a guard.
|
|
160
|
+
const _attachedSignals = new Set();
|
|
156
161
|
// Converts a ShareContent (with portable ShareFile descriptors) to the navigator.share data shape,
|
|
157
162
|
// converting ShareFile data URLs to DOM File objects at the web boundary.
|
|
158
163
|
function shareContentToNavigatorData(content) {
|
|
@@ -169,9 +174,16 @@ function shareContentToNavigatorData(content) {
|
|
|
169
174
|
return data;
|
|
170
175
|
}
|
|
171
176
|
// Converts a portable ShareFile descriptor to a DOM File for navigator.share / navigator.canShare.
|
|
177
|
+
// Throws on a data URL with no comma, which the backend's try/catch turns into the ordinary false
|
|
178
|
+
// sentinel. That is deliberate: the previous code let a missing comma through as index -1, which
|
|
179
|
+
// makes `substring(0, -1)` empty and `substring(0)` the whole string, so a malformed descriptor
|
|
180
|
+
// produced a plausible-looking File containing the URL text instead of failing. A share that
|
|
181
|
+
// silently sends the wrong bytes is worse than one that reports it could not share.
|
|
172
182
|
function shareFileToDomFile(file) {
|
|
173
183
|
// Parse the data URL: 'data:<mimeType>;base64,<data>' or 'data:<mimeType>,<data>'
|
|
174
184
|
const comma = file.dataUrl.indexOf(',');
|
|
185
|
+
if (comma === -1)
|
|
186
|
+
throw new Error('share: dataUrl is not a data URL (no comma)');
|
|
175
187
|
const header = file.dataUrl.substring(0, comma);
|
|
176
188
|
const body = file.dataUrl.substring(comma + 1);
|
|
177
189
|
const isBase64 = header.includes(';base64');
|
package/dist/share.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"share.js","sourceRoot":"","sources":["../src/share.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"share.js","sourceRoot":"","sources":["../src/share.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flighthq/share",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1-next.209.43ef1bc",
|
|
4
|
+
"author": "Joshua Granick and other contributors",
|
|
5
|
+
"license": "MIT",
|
|
4
6
|
"repository": {
|
|
5
7
|
"type": "git",
|
|
6
8
|
"url": "https://github.com/flighthq/flight.git",
|
|
@@ -36,8 +38,8 @@
|
|
|
36
38
|
"clean:dist": "tsx ../../scripts/clean-package-dist.ts"
|
|
37
39
|
},
|
|
38
40
|
"dependencies": {
|
|
39
|
-
"@flighthq/signals": "0.3.
|
|
40
|
-
"@flighthq/types": "0.3.
|
|
41
|
+
"@flighthq/signals": "0.3.1-next.209.43ef1bc",
|
|
42
|
+
"@flighthq/types": "0.3.1-next.209.43ef1bc"
|
|
41
43
|
},
|
|
42
44
|
"devDependencies": {
|
|
43
45
|
"typescript": "^5.3.0"
|
package/src/share.test.ts
CHANGED
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
setShareBackend,
|
|
15
15
|
shareContent,
|
|
16
16
|
shareContentWithResult,
|
|
17
|
+
shareFiles,
|
|
17
18
|
shareText,
|
|
18
19
|
shareUrl,
|
|
19
20
|
} from './share';
|
|
@@ -406,6 +407,48 @@ describe('shareContentWithResult', () => {
|
|
|
406
407
|
});
|
|
407
408
|
});
|
|
408
409
|
|
|
410
|
+
describe('shareFiles', () => {
|
|
411
|
+
const file: ShareFile = { dataUrl: 'data:text/plain;base64,aGk=', mimeType: 'text/plain', name: 'hi.txt' };
|
|
412
|
+
|
|
413
|
+
it('shares via shareContent with a files payload', async () => {
|
|
414
|
+
const backend = fakeBackend();
|
|
415
|
+
setShareBackend(backend);
|
|
416
|
+
expect(await shareFiles([file])).toBe(true);
|
|
417
|
+
expect(backend.shared).toEqual({ files: [file] });
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
it('passes options through', async () => {
|
|
421
|
+
let passedOptions: ShareOptions | undefined;
|
|
422
|
+
setShareBackend({
|
|
423
|
+
isAvailable: () => true,
|
|
424
|
+
canShare: () => true,
|
|
425
|
+
share: async (_content, options) => {
|
|
426
|
+
passedOptions = options;
|
|
427
|
+
return true;
|
|
428
|
+
},
|
|
429
|
+
shareWithResult: async () => ({ completed: true, activityType: null, dismissed: false }),
|
|
430
|
+
});
|
|
431
|
+
const opts: ShareOptions = { chooserTitle: 'Share files' };
|
|
432
|
+
await shareFiles([file], opts);
|
|
433
|
+
expect(passedOptions).toEqual(opts);
|
|
434
|
+
});
|
|
435
|
+
|
|
436
|
+
it('resolves false for an empty array without reaching the backend', async () => {
|
|
437
|
+
const backend = fakeBackend();
|
|
438
|
+
setShareBackend(backend);
|
|
439
|
+
expect(await shareFiles([])).toBe(false);
|
|
440
|
+
expect(backend.shared).toBeNull();
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
it('carries several files in order', async () => {
|
|
444
|
+
const backend = fakeBackend();
|
|
445
|
+
setShareBackend(backend);
|
|
446
|
+
const second: ShareFile = { dataUrl: 'data:text/plain,two', mimeType: 'text/plain', name: 'two.txt' };
|
|
447
|
+
await shareFiles([file, second]);
|
|
448
|
+
expect(backend.shared?.files).toEqual([file, second]);
|
|
449
|
+
});
|
|
450
|
+
});
|
|
451
|
+
|
|
409
452
|
describe('shareText', () => {
|
|
410
453
|
it('shares via shareContent with text payload', async () => {
|
|
411
454
|
const backend = fakeBackend();
|
|
@@ -455,3 +498,30 @@ describe('shareUrl', () => {
|
|
|
455
498
|
expect(passedOptions).toEqual(opts);
|
|
456
499
|
});
|
|
457
500
|
});
|
|
501
|
+
|
|
502
|
+
describe('web backend file conversion', () => {
|
|
503
|
+
it('reports a malformed data URL as unshareable rather than sending the wrong bytes', () => {
|
|
504
|
+
// A dataUrl with no comma used to slip through: indexOf returned -1, so the header read as ''
|
|
505
|
+
// and the body as the whole string, and the converter produced a plausible File containing the
|
|
506
|
+
// URL text. Failing to the ordinary false sentinel is the honest answer.
|
|
507
|
+
mockNavigator({ share: () => Promise.resolve(), canShare: () => true });
|
|
508
|
+
const backend = createWebShareBackend();
|
|
509
|
+
expect(
|
|
510
|
+
backend.canShare({ files: [{ dataUrl: 'data:text/plain;base64', mimeType: 'text/plain', name: 'a.txt' }] }),
|
|
511
|
+
).toBe(false);
|
|
512
|
+
});
|
|
513
|
+
|
|
514
|
+
it('still converts a well-formed data URL', () => {
|
|
515
|
+
mockNavigator({ share: () => Promise.resolve(), canShare: () => true });
|
|
516
|
+
const backend = createWebShareBackend();
|
|
517
|
+
expect(
|
|
518
|
+
backend.canShare({ files: [{ dataUrl: 'data:text/plain;base64,aGk=', mimeType: 'text/plain', name: 'a.txt' }] }),
|
|
519
|
+
).toBe(true);
|
|
520
|
+
});
|
|
521
|
+
|
|
522
|
+
it('rejects a malformed data URL on the share path too, not only the probe', async () => {
|
|
523
|
+
mockNavigator({ share: () => Promise.resolve(), canShare: () => true });
|
|
524
|
+
const backend = createWebShareBackend();
|
|
525
|
+
expect(await backend.share({ files: [{ dataUrl: 'nope', mimeType: 'text/plain', name: 'a.txt' }] })).toBe(false);
|
|
526
|
+
});
|
|
527
|
+
});
|