@tinkerlandai/longplay-react-native 0.10.8 → 0.10.13
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.cjs +2 -2
- package/dist/index.d.cts +26549 -12669
- package/dist/index.d.ts +26549 -12669
- package/dist/index.js +2 -2
- package/native-sdk/android/assets/indiana/index.html +42 -42
- package/native-sdk/android/java/ai/tinkerland/indiana/BundledWebView.kt +6 -2
- package/native-sdk/android/java/ai/tinkerland/indiana/CustomerSession.kt +9 -3
- package/native-sdk/android/java/ai/tinkerland/indiana/FeatureClient.kt +46 -22
- package/native-sdk/android/java/ai/tinkerland/indiana/FunnelConfigurationRelay.kt +47 -21
- package/native-sdk/android/java/ai/tinkerland/indiana/FunnelProcess.kt +120 -0
- package/native-sdk/android/java/ai/tinkerland/indiana/FunnelSession.kt +57 -16
- package/native-sdk/android/java/ai/tinkerland/indiana/GoogleStorefront.kt +18 -2
- package/native-sdk/android/java/ai/tinkerland/indiana/HTTPTransport.kt +48 -20
- package/native-sdk/android/java/ai/tinkerland/indiana/IndianaClient.kt +36 -44
- package/native-sdk/android/java/ai/tinkerland/indiana/PaywallSession.kt +82 -59
- package/native-sdk/android/java/ai/tinkerland/indiana/SDKVersion.kt +1 -1
- package/native-sdk/android/java/ai/tinkerland/indiana/WireSchema.kt +3 -1
- package/native-sdk/android/java/ai/tinkerland/longplay/Longplay.kt +3 -0
- package/native-sdk/android/resources/funnel-wire-schemas.json +1 -1
- package/native-sdk/ios/BundledWebView.swift +5 -1
- package/native-sdk/ios/CustomerSession.swift +7 -3
- package/native-sdk/ios/FeatureClient.swift +75 -29
- package/native-sdk/ios/FunnelConfigurationRelay.swift +1 -0
- package/native-sdk/ios/FunnelProcess.swift +148 -0
- package/native-sdk/ios/FunnelSession.swift +37 -9
- package/native-sdk/ios/HTTPTransport.swift +2 -0
- package/native-sdk/ios/IndianaClient.swift +25 -60
- package/native-sdk/ios/NativeReceiptRelay.swift +3 -3
- package/native-sdk/ios/PaywallSession.swift +5 -4
- package/native-sdk/ios/SDKVersion.swift +1 -1
- package/native-sdk/ios/WebView/index.html +42 -42
- package/native-sdk/ios/funnel-wire-schemas.json +1 -1
- package/package.json +1 -1
- package/native-sdk/android/java/ai/tinkerland/indiana/NativePendingKeystore.kt +0 -81
- package/native-sdk/ios/NativePendingKeychain.swift +0 -52
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import Foundation
|
|
2
2
|
|
|
3
|
-
struct IndianaNativeCompletion: Codable, Sendable { let orderId: UUID; let receiptId: UUID; let membership: Bool; let transactionIds: [String] }
|
|
4
|
-
|
|
5
3
|
/// HTTPS endpoint on your own backend. It authenticates the customer and attaches the Indiana server key there.
|
|
6
4
|
public final class IndianaNativeReceiptRelay: Sendable {
|
|
7
5
|
private let endpoint: URL; private let session: URLSession
|
|
8
6
|
public init(endpoint: URL) throws {
|
|
9
7
|
guard endpoint.scheme == "https", endpoint.host != nil, endpoint.user == nil, endpoint.password == nil, endpoint.query == nil, endpoint.fragment == nil else { throw IndianaClientError.invalidConfiguration }
|
|
10
8
|
self.endpoint = endpoint
|
|
11
|
-
let config = URLSessionConfiguration.ephemeral; config.urlCache = nil; config.httpCookieStorage = nil; config.requestCachePolicy = .reloadIgnoringLocalCacheData; config.timeoutIntervalForRequest = 35
|
|
9
|
+
let config = URLSessionConfiguration.ephemeral; config.urlCache = nil; config.httpCookieStorage = nil; config.requestCachePolicy = .reloadIgnoringLocalCacheData; config.timeoutIntervalForRequest = 35; config.timeoutIntervalForResource = 35
|
|
12
10
|
session = URLSession(configuration: config, delegate: NoRedirect(), delegateQueue: nil)
|
|
13
11
|
}
|
|
12
|
+
deinit { session.invalidateAndCancel() }
|
|
14
13
|
public func send(_ body: Data) async throws -> Data {
|
|
15
14
|
guard body.count <= 262144, let input = try? JSONDecoder().decode(IndianaJSON.self, from: body).object, input["operation"] == .string("native_receipt"), let token = input["customerToken"]?.string, token.range(of: "^gg_ct_[A-Za-z0-9_-]{32,128}$", options: .regularExpression) != nil else { throw IndianaClientError.invalidConfiguration }
|
|
16
15
|
var request = URLRequest(url: endpoint); request.httpMethod = "POST"; request.httpBody = body
|
|
17
16
|
request.setValue("application/json", forHTTPHeaderField: "Content-Type"); request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
|
|
18
17
|
do {
|
|
19
18
|
let (stream, response) = try await session.bytes(for: request)
|
|
19
|
+
defer { stream.task.cancel() }
|
|
20
20
|
guard let http = response as? HTTPURLResponse, (200..<300).contains(http.statusCode) else { throw IndianaClientError.requestFailed((response as? HTTPURLResponse)?.statusCode ?? 0) }
|
|
21
21
|
guard response.expectedContentLength <= 262144 else { throw IndianaClientError.invalidResponse }
|
|
22
22
|
var result = Data(); for try await byte in stream { guard result.count < 262144 else { throw IndianaClientError.invalidResponse }; result.append(byte) }; return result
|
|
@@ -52,7 +52,8 @@ public actor IndianaPaywallSession {
|
|
|
52
52
|
private func canonical(_ value: IndianaJSON) throws -> Data { let encoder = JSONEncoder(); encoder.outputFormatting = .sortedKeys; return try encoder.encode(value) }
|
|
53
53
|
public func refresh() async throws -> IndianaJSON { try await hostCommand(.object(["operation":.string("resolve"),"input":.object([:])])) }
|
|
54
54
|
internal func hostCommand(_ payload: IndianaJSON) async throws -> IndianaJSON {
|
|
55
|
-
guard !closed,
|
|
55
|
+
guard !closed, let envelope = payload.object, Set(envelope.keys) == Set(["operation","input"]), let action = envelope["operation"]?.string, let input = envelope["input"]?.object else { throw IndianaFunnelError.invalidCommand }
|
|
56
|
+
guard !busy else { throw IndianaFunnelError.commandPending }
|
|
56
57
|
busy = true; defer { busy = false }
|
|
57
58
|
switch action {
|
|
58
59
|
case "resolve":
|
|
@@ -78,7 +79,6 @@ public actor IndianaPaywallSession {
|
|
|
78
79
|
let fingerprint = try canonical(payload)
|
|
79
80
|
if let pendingPreview, pendingPreview != fingerprint {
|
|
80
81
|
guard let status = operation?.object?["status"]?.string, status != "pending" else { throw IndianaFunnelError.commandPending }
|
|
81
|
-
quote = nil; operation = nil
|
|
82
82
|
}
|
|
83
83
|
if pendingPreview == fingerprint, let quote { return quote }
|
|
84
84
|
var selectedPlan: [String:IndianaJSON] = ["productVersionId":.string(product)]
|
|
@@ -87,6 +87,7 @@ public actor IndianaPaywallSession {
|
|
|
87
87
|
fields["offerId"] = input["offerId"]; fields["nativeOffer"] = input["nativeOffer"]
|
|
88
88
|
let body = IndianaJSON.object(fields)
|
|
89
89
|
try IndianaSchema.validate("previewAttachRequest", data: JSONEncoder().encode(body))
|
|
90
|
+
if pendingPreview != fingerprint { quote = nil; operation = nil }
|
|
90
91
|
pendingPreview = fingerprint
|
|
91
92
|
let reply = try await send("previewAttach", path:"subscriptions/preview-attach",body:body)
|
|
92
93
|
guard let value = reply.object?["quote"], let q = value.object, q["currency"]?.string == currency, q["provider"]?.string == provider.rawValue,
|
|
@@ -97,9 +98,9 @@ public actor IndianaPaywallSession {
|
|
|
97
98
|
let body = action == "read" ? IndianaJSON.object(["operationId":id]) : .object(["operationId":id,"intent":.string(action)])
|
|
98
99
|
let reply = try await send(action == "read" ? "readSubscriptionOperation" : "attach", path: action == "read" ? "subscriptions/operations/read" : "subscriptions/attach", body:body)
|
|
99
100
|
guard let value = reply.object?["operation"], value.object?["operationId"] == id, value.object?["currency"]?.string == currency else { throw IndianaClientError.invalidResponse }
|
|
100
|
-
if operation
|
|
101
|
+
if let previous = operation, let status = previous.object?["status"]?.string,
|
|
102
|
+
status == "complete" || status != "pending" && value.object?["status"]?.string == "pending" { return previous }
|
|
101
103
|
operation = value
|
|
102
|
-
if value.object?["status"]?.string != "pending" && value.object?["status"]?.string != "complete" { pendingPreview = nil; quote = nil }
|
|
103
104
|
return value
|
|
104
105
|
default: throw IndianaFunnelError.invalidCommand
|
|
105
106
|
}
|