Skip to content

Commit 05ae626

Browse files
committed
fix: preserve pending import until consumed
1 parent f351fd3 commit 05ae626

2 files changed

Lines changed: 93 additions & 8 deletions

File tree

‎assets/react/src/lib/native-shared-import.ts‎

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,34 @@ function isNativeLinkPayload(payload?: NativeOpenPayload | null): payload is Ext
3636
return Boolean(payload && "url" in payload && payload.url.trim())
3737
}
3838

39+
function receiveSharedImport(payload: SharedImportPayload) {
40+
if (listeners.size === 0) {
41+
pendingImport = payload
42+
return
43+
}
44+
45+
pendingImport = null
46+
for (const listener of listeners) listener(payload)
47+
}
48+
49+
export function receiveNativeOpenPayload(
50+
payload: NativeOpenPayload | null | undefined,
51+
onOpen: (payload: NativeOpenPayload) => void,
52+
) {
53+
if (isSharedImportPayload(payload)) {
54+
receiveSharedImport(payload)
55+
onOpen(payload)
56+
return true
57+
}
58+
59+
if (isNativeLinkPayload(payload)) {
60+
onOpen(payload)
61+
return true
62+
}
63+
64+
return false
65+
}
66+
3967
export function takeSharedImport() {
4068
const payload = pendingImport
4169
pendingImport = null
@@ -44,6 +72,10 @@ export function takeSharedImport() {
4472

4573
export function subscribeSharedImport(listener: (payload: SharedImportPayload) => void) {
4674
listeners.add(listener)
75+
76+
const payload = takeSharedImport()
77+
if (payload) listener(payload)
78+
4779
return () => {
4880
listeners.delete(listener)
4981
}
@@ -53,14 +85,7 @@ export async function initializeNativeSharedImport(onOpen: (payload: NativeOpenP
5385
if (!Capacitor.isNativePlatform()) return
5486

5587
const receive = (payload?: NativeOpenPayload | null) => {
56-
if (isSharedImportPayload(payload)) {
57-
pendingImport = payload
58-
for (const listener of listeners) listener(payload)
59-
onOpen(payload)
60-
return
61-
}
62-
63-
if (isNativeLinkPayload(payload)) onOpen(payload)
88+
receiveNativeOpenPayload(payload, onOpen)
6489
}
6590

6691
try {
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import test from "node:test"
2+
import assert from "node:assert/strict"
3+
4+
import {
5+
receiveNativeOpenPayload,
6+
subscribeSharedImport,
7+
takeSharedImport,
8+
} from "../src/lib/native-shared-import.ts"
9+
10+
const sharedPayload = {
11+
text: "1 Lightning Bolt",
12+
fileName: "manabox.txt",
13+
mimeType: "text/plain",
14+
source: "android-share",
15+
}
16+
17+
test("receiveNativeOpenPayload stores shared imports until the collection route consumes them", () => {
18+
const opened = []
19+
20+
assert.equal(receiveNativeOpenPayload(sharedPayload, (payload) => opened.push(payload)), true)
21+
assert.deepEqual(opened, [sharedPayload])
22+
assert.deepEqual(takeSharedImport(), sharedPayload)
23+
assert.equal(takeSharedImport(), null)
24+
})
25+
26+
test("subscribeSharedImport immediately delivers a pending shared import", () => {
27+
const opened = []
28+
const delivered = []
29+
30+
receiveNativeOpenPayload(sharedPayload, (payload) => opened.push(payload))
31+
const unsubscribe = subscribeSharedImport((payload) => delivered.push(payload))
32+
unsubscribe()
33+
34+
assert.deepEqual(opened, [sharedPayload])
35+
assert.deepEqual(delivered, [sharedPayload])
36+
assert.equal(takeSharedImport(), null)
37+
})
38+
39+
test("receiveNativeOpenPayload sends active subscribers without leaving stale pending imports", () => {
40+
const opened = []
41+
const delivered = []
42+
const unsubscribe = subscribeSharedImport((payload) => delivered.push(payload))
43+
44+
assert.equal(receiveNativeOpenPayload(sharedPayload, (payload) => opened.push(payload)), true)
45+
unsubscribe()
46+
47+
assert.deepEqual(opened, [sharedPayload])
48+
assert.deepEqual(delivered, [sharedPayload])
49+
assert.equal(takeSharedImport(), null)
50+
})
51+
52+
test("receiveNativeOpenPayload routes native links without creating a shared import", () => {
53+
const linkPayload = { url: "https://manavault.cfb.dev/collection", source: "android-view" }
54+
const opened = []
55+
56+
assert.equal(receiveNativeOpenPayload(linkPayload, (payload) => opened.push(payload)), true)
57+
58+
assert.deepEqual(opened, [linkPayload])
59+
assert.equal(takeSharedImport(), null)
60+
})

0 commit comments

Comments
 (0)