jazz-tools 0.19.8 → 0.19.11
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/.turbo/turbo-build.log +56 -50
- package/CHANGELOG.md +30 -3
- package/dist/{chunk-2S3Z2CN6.js → chunk-HX5S6W5E.js} +372 -103
- package/dist/chunk-HX5S6W5E.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/inspector/account-switcher.d.ts +4 -0
- package/dist/inspector/account-switcher.d.ts.map +1 -0
- package/dist/inspector/chunk-C6BJPHBQ.js +4096 -0
- package/dist/inspector/chunk-C6BJPHBQ.js.map +1 -0
- package/dist/inspector/contexts/node.d.ts +19 -0
- package/dist/inspector/contexts/node.d.ts.map +1 -0
- package/dist/inspector/{custom-element-P76EIWEV.js → custom-element-GJVBPZES.js} +1011 -884
- package/dist/inspector/custom-element-GJVBPZES.js.map +1 -0
- package/dist/inspector/{viewer/new-app.d.ts → in-app.d.ts} +3 -3
- package/dist/inspector/in-app.d.ts.map +1 -0
- package/dist/inspector/index.d.ts +0 -11
- package/dist/inspector/index.d.ts.map +1 -1
- package/dist/inspector/index.js +56 -3910
- package/dist/inspector/index.js.map +1 -1
- package/dist/inspector/pages/home.d.ts +2 -0
- package/dist/inspector/pages/home.d.ts.map +1 -0
- package/dist/inspector/register-custom-element.js +1 -1
- package/dist/inspector/router/context.d.ts +12 -0
- package/dist/inspector/router/context.d.ts.map +1 -0
- package/dist/inspector/router/hash-router.d.ts +7 -0
- package/dist/inspector/router/hash-router.d.ts.map +1 -0
- package/dist/inspector/router/in-memory-router.d.ts +7 -0
- package/dist/inspector/router/in-memory-router.d.ts.map +1 -0
- package/dist/inspector/router/index.d.ts +5 -0
- package/dist/inspector/router/index.d.ts.map +1 -0
- package/dist/inspector/standalone.d.ts +6 -0
- package/dist/inspector/standalone.d.ts.map +1 -0
- package/dist/inspector/standalone.js +420 -0
- package/dist/inspector/standalone.js.map +1 -0
- package/dist/inspector/tests/router/hash-router.test.d.ts +2 -0
- package/dist/inspector/tests/router/hash-router.test.d.ts.map +1 -0
- package/dist/inspector/tests/router/in-memory-router.test.d.ts +2 -0
- package/dist/inspector/tests/router/in-memory-router.test.d.ts.map +1 -0
- package/dist/inspector/ui/modal.d.ts +1 -0
- package/dist/inspector/ui/modal.d.ts.map +1 -1
- package/dist/inspector/viewer/breadcrumbs.d.ts +1 -7
- package/dist/inspector/viewer/breadcrumbs.d.ts.map +1 -1
- package/dist/inspector/viewer/header.d.ts +7 -0
- package/dist/inspector/viewer/header.d.ts.map +1 -0
- package/dist/inspector/viewer/page-stack.d.ts +4 -13
- package/dist/inspector/viewer/page-stack.d.ts.map +1 -1
- package/dist/inspector/viewer/page.d.ts.map +1 -1
- package/dist/react/hooks.d.ts +1 -1
- package/dist/react/hooks.d.ts.map +1 -1
- package/dist/react/index.d.ts +1 -1
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +5 -1
- package/dist/react/index.js.map +1 -1
- package/dist/react-core/hooks.d.ts +59 -0
- package/dist/react-core/hooks.d.ts.map +1 -1
- package/dist/react-core/index.js +124 -36
- package/dist/react-core/index.js.map +1 -1
- package/dist/react-core/tests/testUtils.d.ts +1 -0
- package/dist/react-core/tests/testUtils.d.ts.map +1 -1
- package/dist/react-core/tests/useSuspenseAccount.test.d.ts +2 -0
- package/dist/react-core/tests/useSuspenseAccount.test.d.ts.map +1 -0
- package/dist/react-core/tests/useSuspenseCoState.test.d.ts +2 -0
- package/dist/react-core/tests/useSuspenseCoState.test.d.ts.map +1 -0
- package/dist/react-core/use.d.ts +3 -0
- package/dist/react-core/use.d.ts.map +1 -0
- package/dist/react-native/index.js +5 -1
- package/dist/react-native/index.js.map +1 -1
- package/dist/react-native-core/crypto/RNCrypto.d.ts +2 -0
- package/dist/react-native-core/crypto/RNCrypto.d.ts.map +1 -0
- package/dist/react-native-core/crypto/RNCrypto.js +3 -0
- package/dist/react-native-core/crypto/RNCrypto.js.map +1 -0
- package/dist/react-native-core/hooks.d.ts +1 -1
- package/dist/react-native-core/hooks.d.ts.map +1 -1
- package/dist/react-native-core/index.js +5 -1
- package/dist/react-native-core/index.js.map +1 -1
- package/dist/react-native-core/platform.d.ts +2 -1
- package/dist/react-native-core/platform.d.ts.map +1 -1
- package/dist/testing.js +1 -1
- package/dist/testing.js.map +1 -1
- package/dist/tools/coValues/account.d.ts +7 -1
- package/dist/tools/coValues/account.d.ts.map +1 -1
- package/dist/tools/coValues/interfaces.d.ts +1 -1
- package/dist/tools/coValues/interfaces.d.ts.map +1 -1
- package/dist/tools/implementation/ContextManager.d.ts +3 -0
- package/dist/tools/implementation/ContextManager.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/AccountSchema.d.ts +8 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/AccountSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/zodCo.d.ts.map +1 -1
- package/dist/tools/subscribe/CoValueCoreSubscription.d.ts +8 -22
- package/dist/tools/subscribe/CoValueCoreSubscription.d.ts.map +1 -1
- package/dist/tools/subscribe/SubscriptionCache.d.ts +51 -0
- package/dist/tools/subscribe/SubscriptionCache.d.ts.map +1 -0
- package/dist/tools/subscribe/SubscriptionScope.d.ts +17 -1
- package/dist/tools/subscribe/SubscriptionScope.d.ts.map +1 -1
- package/dist/tools/subscribe/utils.d.ts +9 -1
- package/dist/tools/subscribe/utils.d.ts.map +1 -1
- package/dist/tools/testing.d.ts +2 -2
- package/dist/tools/testing.d.ts.map +1 -1
- package/dist/tools/tests/SubscriptionCache.test.d.ts +2 -0
- package/dist/tools/tests/SubscriptionCache.test.d.ts.map +1 -0
- package/package.json +18 -6
- package/src/inspector/account-switcher.tsx +440 -0
- package/src/inspector/contexts/node.tsx +129 -0
- package/src/inspector/custom-element.tsx +2 -2
- package/src/inspector/in-app.tsx +61 -0
- package/src/inspector/index.tsx +2 -22
- package/src/inspector/pages/home.tsx +77 -0
- package/src/inspector/router/context.ts +21 -0
- package/src/inspector/router/hash-router.tsx +128 -0
- package/src/inspector/{viewer/use-page-path.ts → router/in-memory-router.tsx} +31 -29
- package/src/inspector/router/index.ts +4 -0
- package/src/inspector/standalone.tsx +60 -0
- package/src/inspector/tests/router/hash-router.test.tsx +847 -0
- package/src/inspector/tests/router/in-memory-router.test.tsx +724 -0
- package/src/inspector/ui/modal.tsx +5 -2
- package/src/inspector/viewer/breadcrumbs.tsx +5 -11
- package/src/inspector/viewer/header.tsx +67 -0
- package/src/inspector/viewer/page-stack.tsx +18 -26
- package/src/inspector/viewer/page.tsx +0 -1
- package/src/react/hooks.tsx +2 -0
- package/src/react/index.ts +1 -14
- package/src/react-core/hooks.ts +167 -18
- package/src/react-core/tests/createCoValueSubscriptionContext.test.tsx +18 -8
- package/src/react-core/tests/testUtils.tsx +67 -5
- package/src/react-core/tests/useCoState.test.ts +3 -7
- package/src/react-core/tests/useSubscriptionSelector.test.ts +3 -7
- package/src/react-core/tests/useSuspenseAccount.test.tsx +343 -0
- package/src/react-core/tests/useSuspenseCoState.test.tsx +1182 -0
- package/src/react-core/use.ts +46 -0
- package/src/react-native-core/crypto/RNCrypto.ts +1 -0
- package/src/react-native-core/hooks.tsx +2 -0
- package/src/react-native-core/platform.ts +2 -1
- package/src/tools/coValues/account.ts +13 -2
- package/src/tools/coValues/interfaces.ts +2 -3
- package/src/tools/implementation/ContextManager.ts +13 -0
- package/src/tools/implementation/zodSchema/schemaTypes/AccountSchema.ts +8 -1
- package/src/tools/subscribe/CoValueCoreSubscription.ts +71 -100
- package/src/tools/subscribe/SubscriptionCache.ts +272 -0
- package/src/tools/subscribe/SubscriptionScope.ts +113 -7
- package/src/tools/subscribe/utils.ts +77 -0
- package/src/tools/testing.ts +0 -3
- package/src/tools/tests/CoValueCoreSubscription.test.ts +46 -12
- package/src/tools/tests/ContextManager.test.ts +85 -0
- package/src/tools/tests/SubscriptionCache.test.ts +237 -0
- package/src/tools/tests/account.test.ts +11 -4
- package/src/tools/tests/coMap.test.ts +5 -7
- package/src/tools/tests/schema.resolved.test.ts +3 -3
- package/tsup.config.ts +2 -0
- package/dist/chunk-2S3Z2CN6.js.map +0 -1
- package/dist/inspector/custom-element-P76EIWEV.js.map +0 -1
- package/dist/inspector/viewer/new-app.d.ts.map +0 -1
- package/dist/inspector/viewer/use-page-path.d.ts +0 -10
- package/dist/inspector/viewer/use-page-path.d.ts.map +0 -1
- package/src/inspector/viewer/new-app.tsx +0 -156
|
@@ -2308,6 +2308,10 @@ var _Account = class _Account extends CoValueBase {
|
|
|
2308
2308
|
crypto,
|
|
2309
2309
|
peers: [connectedPeers[0]]
|
|
2310
2310
|
});
|
|
2311
|
+
const credentials = {
|
|
2312
|
+
accountID: account.$jazz.id,
|
|
2313
|
+
accountSecret: account.$jazz.localNode.getCurrentAgent().agentSecret
|
|
2314
|
+
};
|
|
2311
2315
|
const loadedWorker = await _Account.load(worker.$jazz.id, {
|
|
2312
2316
|
loadAs: account
|
|
2313
2317
|
});
|
|
@@ -2321,7 +2325,7 @@ var _Account = class _Account extends CoValueBase {
|
|
|
2321
2325
|
if (!createdAccount.$isLoaded)
|
|
2322
2326
|
throw new Error("Unable to load the created account");
|
|
2323
2327
|
account.$jazz.localNode.gracefulShutdown();
|
|
2324
|
-
return createdAccount;
|
|
2328
|
+
return { credentials, account: createdAccount };
|
|
2325
2329
|
}
|
|
2326
2330
|
static fromNode(node) {
|
|
2327
2331
|
return new this({
|
|
@@ -3930,7 +3934,8 @@ function applyCoValueMigrations(instance) {
|
|
|
3930
3934
|
|
|
3931
3935
|
// src/tools/subscribe/CoValueCoreSubscription.ts
|
|
3932
3936
|
import {
|
|
3933
|
-
cojsonInternals as cojsonInternals4
|
|
3937
|
+
cojsonInternals as cojsonInternals4,
|
|
3938
|
+
isRawCoID
|
|
3934
3939
|
} from "cojson";
|
|
3935
3940
|
|
|
3936
3941
|
// src/tools/subscribe/types.ts
|
|
@@ -3984,101 +3989,62 @@ var CoValueCoreSubscription = class {
|
|
|
3984
3989
|
*/
|
|
3985
3990
|
initializeSubscription() {
|
|
3986
3991
|
const source = this.source;
|
|
3987
|
-
if (source.
|
|
3988
|
-
this.
|
|
3992
|
+
if (!isRawCoID(source.id)) {
|
|
3993
|
+
this.emit(CoValueLoadingState.UNAVAILABLE);
|
|
3989
3994
|
return;
|
|
3990
3995
|
}
|
|
3991
3996
|
if (this.branchName) {
|
|
3992
|
-
this.
|
|
3997
|
+
this.handleBranching(this.branchName, this.branchOwnerId);
|
|
3993
3998
|
return;
|
|
3994
3999
|
}
|
|
3995
|
-
this.
|
|
4000
|
+
this.subscribe(this.source);
|
|
3996
4001
|
}
|
|
3997
|
-
|
|
3998
|
-
|
|
3999
|
-
|
|
4000
|
-
|
|
4001
|
-
handleAvailableSource() {
|
|
4002
|
-
if (!this.branchName || !cojsonInternals4.canBeBranched(this.source)) {
|
|
4003
|
-
this.subscribe(this.source.getCurrentContent());
|
|
4002
|
+
handleBranching(branchName, branchOwnerId) {
|
|
4003
|
+
const source = this.source;
|
|
4004
|
+
if (!source.isAvailable()) {
|
|
4005
|
+
this.waitForSourceToBecomeAvailable(branchName, branchOwnerId);
|
|
4004
4006
|
return;
|
|
4005
4007
|
}
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
this.subscribe(branch.getCurrentContent());
|
|
4008
|
+
if (!cojsonInternals4.canBeBranched(source)) {
|
|
4009
|
+
this.subscribe(source);
|
|
4009
4010
|
return;
|
|
4010
|
-
} else if (!this.source.hasBranch(this.branchName, this.branchOwnerId)) {
|
|
4011
|
-
this.source.createBranch(this.branchName, this.branchOwnerId);
|
|
4012
|
-
this.subscribe(branch.getCurrentContent());
|
|
4013
|
-
} else {
|
|
4014
|
-
this.handleBranchCheckout();
|
|
4015
4011
|
}
|
|
4016
|
-
|
|
4017
|
-
|
|
4018
|
-
|
|
4019
|
-
|
|
4020
|
-
|
|
4021
|
-
|
|
4022
|
-
|
|
4023
|
-
|
|
4024
|
-
if (value !== CoValueLoadingState.UNAVAILABLE) {
|
|
4025
|
-
this.subscribe(value);
|
|
4026
|
-
} else {
|
|
4027
|
-
this.handleUnavailableBranch();
|
|
4012
|
+
const branch = source.getBranch(branchName, branchOwnerId);
|
|
4013
|
+
if (!branch.isAvailable() && !source.hasBranch(branchName, branchOwnerId)) {
|
|
4014
|
+
try {
|
|
4015
|
+
source.createBranch(branchName, branchOwnerId);
|
|
4016
|
+
} catch (error) {
|
|
4017
|
+
console.error("error creating branch", error);
|
|
4018
|
+
this.emit(CoValueLoadingState.UNAVAILABLE);
|
|
4019
|
+
return;
|
|
4028
4020
|
}
|
|
4029
|
-
}).catch((error) => {
|
|
4030
|
-
console.error(error);
|
|
4031
|
-
this.emit(CoValueLoadingState.UNAVAILABLE);
|
|
4032
|
-
});
|
|
4033
|
-
}
|
|
4034
|
-
/**
|
|
4035
|
-
* Handles the case where a branch checkout fails.
|
|
4036
|
-
* Determines whether to retry or report unavailability.
|
|
4037
|
-
*/
|
|
4038
|
-
handleUnavailableBranch() {
|
|
4039
|
-
const source = this.source;
|
|
4040
|
-
if (source.isAvailable()) {
|
|
4041
|
-
throw new Error("Branch is unavailable");
|
|
4042
4021
|
}
|
|
4043
|
-
this.
|
|
4044
|
-
this.emit(CoValueLoadingState.UNAVAILABLE);
|
|
4022
|
+
this.subscribe(branch);
|
|
4045
4023
|
}
|
|
4046
4024
|
/**
|
|
4047
|
-
* Loads
|
|
4048
|
-
* This is the fallback strategy when immediate availability fails.
|
|
4025
|
+
* Loads a CoValue core and emits an unavailable event if it is still unavailable after the retries.
|
|
4049
4026
|
*/
|
|
4050
|
-
|
|
4051
|
-
this.localNode.loadCoValueCore(
|
|
4052
|
-
if (
|
|
4053
|
-
if (value.isAvailable()) {
|
|
4054
|
-
this.subscribe(value.getCurrentContent());
|
|
4055
|
-
} else {
|
|
4056
|
-
this.subscribeToUnavailableSource();
|
|
4027
|
+
load(value) {
|
|
4028
|
+
this.localNode.loadCoValueCore(value.id, void 0, this.skipRetry).then(() => {
|
|
4029
|
+
if (!value.isAvailable()) {
|
|
4057
4030
|
this.emit(CoValueLoadingState.UNAVAILABLE);
|
|
4058
4031
|
}
|
|
4059
|
-
}).catch((error) => {
|
|
4060
|
-
console.error(error);
|
|
4061
|
-
this.emit(CoValueLoadingState.UNAVAILABLE);
|
|
4062
4032
|
});
|
|
4063
4033
|
}
|
|
4064
4034
|
/**
|
|
4065
|
-
*
|
|
4066
|
-
* This allows the subscription to become active when the source becomes available after a first loading attempt.
|
|
4035
|
+
* Waits for the source to become available and then tries to branch.
|
|
4067
4036
|
*/
|
|
4068
|
-
|
|
4037
|
+
waitForSourceToBecomeAvailable(branchName, branchOwnerId) {
|
|
4069
4038
|
const source = this.source;
|
|
4070
4039
|
const handleStateChange = (_, unsubFromStateChange) => {
|
|
4071
4040
|
if (!source.isAvailable()) {
|
|
4072
4041
|
return;
|
|
4073
4042
|
}
|
|
4074
4043
|
unsubFromStateChange();
|
|
4075
|
-
|
|
4076
|
-
this.handleBranchCheckout();
|
|
4077
|
-
} else {
|
|
4078
|
-
this.subscribe(source.getCurrentContent());
|
|
4079
|
-
}
|
|
4044
|
+
this.handleBranching(branchName, branchOwnerId);
|
|
4080
4045
|
};
|
|
4081
4046
|
this._unsubscribe = source.subscribe(handleStateChange);
|
|
4047
|
+
this.load(source);
|
|
4082
4048
|
}
|
|
4083
4049
|
/**
|
|
4084
4050
|
* Subscribes to a specific CoValue and notifies the listener.
|
|
@@ -4087,16 +4053,30 @@ var CoValueCoreSubscription = class {
|
|
|
4087
4053
|
subscribe(value) {
|
|
4088
4054
|
if (this.unsubscribed) return;
|
|
4089
4055
|
this._unsubscribe = value.subscribe((value2) => {
|
|
4090
|
-
|
|
4056
|
+
if (value2.isAvailable()) {
|
|
4057
|
+
this.emit(value2.getCurrentContent());
|
|
4058
|
+
}
|
|
4091
4059
|
});
|
|
4060
|
+
if (!value.isAvailable()) {
|
|
4061
|
+
this.load(value);
|
|
4062
|
+
}
|
|
4092
4063
|
}
|
|
4093
4064
|
emit(value) {
|
|
4094
4065
|
if (this.unsubscribed) return;
|
|
4095
|
-
if (!isReadyForEmit(value)) {
|
|
4066
|
+
if (!this.isReadyForEmit(value)) {
|
|
4096
4067
|
return;
|
|
4097
4068
|
}
|
|
4098
4069
|
this.listener(value);
|
|
4099
4070
|
}
|
|
4071
|
+
isReadyForEmit(value) {
|
|
4072
|
+
if (value === CoValueLoadingState.UNAVAILABLE) {
|
|
4073
|
+
return true;
|
|
4074
|
+
}
|
|
4075
|
+
if (!isCompletelyDownloaded(value)) {
|
|
4076
|
+
return false;
|
|
4077
|
+
}
|
|
4078
|
+
return true;
|
|
4079
|
+
}
|
|
4100
4080
|
/**
|
|
4101
4081
|
* Unsubscribes from all active subscriptions and marks the instance as unsubscribed.
|
|
4102
4082
|
* This prevents any further operations and ensures proper cleanup.
|
|
@@ -4107,10 +4087,7 @@ var CoValueCoreSubscription = class {
|
|
|
4107
4087
|
this._unsubscribe();
|
|
4108
4088
|
}
|
|
4109
4089
|
};
|
|
4110
|
-
function
|
|
4111
|
-
if (value === "unavailable") {
|
|
4112
|
-
return true;
|
|
4113
|
-
}
|
|
4090
|
+
function isCompletelyDownloaded(value) {
|
|
4114
4091
|
return value.core.verified?.header.meta?.type === "binary" || value.core.isCompletelyDownloaded();
|
|
4115
4092
|
}
|
|
4116
4093
|
|
|
@@ -4148,6 +4125,34 @@ var JazzError = class _JazzError {
|
|
|
4148
4125
|
}
|
|
4149
4126
|
};
|
|
4150
4127
|
|
|
4128
|
+
// src/tools/subscribe/errorReporting.ts
|
|
4129
|
+
var isDev = function() {
|
|
4130
|
+
try {
|
|
4131
|
+
return process.env.NODE_ENV === "development";
|
|
4132
|
+
} catch {
|
|
4133
|
+
return false;
|
|
4134
|
+
}
|
|
4135
|
+
}();
|
|
4136
|
+
var customErrorReporter;
|
|
4137
|
+
var captureErrorCause = isDev;
|
|
4138
|
+
function enableCaptureErrorCause(capture) {
|
|
4139
|
+
captureErrorCause = capture;
|
|
4140
|
+
}
|
|
4141
|
+
function setCustomErrorReporter(reporter) {
|
|
4142
|
+
customErrorReporter = reporter;
|
|
4143
|
+
}
|
|
4144
|
+
function isCustomErrorReportingEnabled() {
|
|
4145
|
+
return customErrorReporter !== void 0;
|
|
4146
|
+
}
|
|
4147
|
+
function captureStack() {
|
|
4148
|
+
return captureErrorCause ? new Error() : void 0;
|
|
4149
|
+
}
|
|
4150
|
+
function captureError(error, props) {
|
|
4151
|
+
if (customErrorReporter) {
|
|
4152
|
+
customErrorReporter(error, props);
|
|
4153
|
+
}
|
|
4154
|
+
}
|
|
4155
|
+
|
|
4151
4156
|
// src/tools/subscribe/utils.ts
|
|
4152
4157
|
import { RawAccount as RawAccount4 } from "cojson";
|
|
4153
4158
|
|
|
@@ -4188,33 +4193,47 @@ function createCoValue(ref2, raw, subscriptionScope) {
|
|
|
4188
4193
|
id: subscriptionScope.id
|
|
4189
4194
|
};
|
|
4190
4195
|
}
|
|
4191
|
-
|
|
4192
|
-
|
|
4193
|
-
|
|
4194
|
-
|
|
4195
|
-
|
|
4196
|
-
} catch {
|
|
4197
|
-
return false;
|
|
4198
|
-
}
|
|
4199
|
-
}();
|
|
4200
|
-
var customErrorReporter;
|
|
4201
|
-
var captureErrorCause = isDev;
|
|
4202
|
-
function enableCaptureErrorCause(capture) {
|
|
4203
|
-
captureErrorCause = capture;
|
|
4204
|
-
}
|
|
4205
|
-
function setCustomErrorReporter(reporter) {
|
|
4206
|
-
customErrorReporter = reporter;
|
|
4207
|
-
}
|
|
4208
|
-
function isCustomErrorReportingEnabled() {
|
|
4209
|
-
return customErrorReporter !== void 0;
|
|
4196
|
+
function resolvedPromise(value) {
|
|
4197
|
+
const promise = Promise.resolve(value);
|
|
4198
|
+
promise.status = "fulfilled";
|
|
4199
|
+
promise.value = value;
|
|
4200
|
+
return promise;
|
|
4210
4201
|
}
|
|
4211
|
-
function
|
|
4212
|
-
|
|
4202
|
+
function rejectedPromise(reason) {
|
|
4203
|
+
const promise = Promise.reject(reason);
|
|
4204
|
+
promise.status = "rejected";
|
|
4205
|
+
promise.reason = reason;
|
|
4206
|
+
return promise;
|
|
4213
4207
|
}
|
|
4214
|
-
function
|
|
4215
|
-
if (
|
|
4216
|
-
|
|
4208
|
+
function isEqualRefsToResolve(a, b) {
|
|
4209
|
+
if (a === b) {
|
|
4210
|
+
return true;
|
|
4211
|
+
}
|
|
4212
|
+
if (typeof a === "boolean" && typeof b === "boolean") {
|
|
4213
|
+
return a === b;
|
|
4214
|
+
}
|
|
4215
|
+
if (typeof a === "boolean" || typeof b === "boolean") {
|
|
4216
|
+
return false;
|
|
4217
|
+
}
|
|
4218
|
+
if (typeof a !== "object" || typeof b !== "object" || a === null || b === null) {
|
|
4219
|
+
return false;
|
|
4220
|
+
}
|
|
4221
|
+
const keysA = Object.keys(a);
|
|
4222
|
+
const keysB = Object.keys(b);
|
|
4223
|
+
if (keysA.length !== keysB.length) {
|
|
4224
|
+
return false;
|
|
4225
|
+
}
|
|
4226
|
+
for (const key of keysA) {
|
|
4227
|
+
if (!(key in b)) {
|
|
4228
|
+
return false;
|
|
4229
|
+
}
|
|
4230
|
+
const valueA = a[key];
|
|
4231
|
+
const valueB = b[key];
|
|
4232
|
+
if (!isEqualRefsToResolve(valueA, valueB)) {
|
|
4233
|
+
return false;
|
|
4234
|
+
}
|
|
4217
4235
|
}
|
|
4236
|
+
return true;
|
|
4218
4237
|
}
|
|
4219
4238
|
|
|
4220
4239
|
// src/tools/subscribe/SubscriptionScope.ts
|
|
@@ -4273,6 +4292,7 @@ var SubscriptionScope = class _SubscriptionScope {
|
|
|
4273
4292
|
this.triggerUpdate();
|
|
4274
4293
|
};
|
|
4275
4294
|
this.subscribers = /* @__PURE__ */ new Set();
|
|
4295
|
+
this.subscriberChangeCallbacks = /* @__PURE__ */ new Set();
|
|
4276
4296
|
this.callerStack = callerStack;
|
|
4277
4297
|
this.resolve = resolve;
|
|
4278
4298
|
this.value = { type: CoValueLoadingState.LOADING, id };
|
|
@@ -4401,6 +4421,48 @@ var SubscriptionScope = class _SubscriptionScope {
|
|
|
4401
4421
|
if (this.value.type !== CoValueLoadingState.LOADED) return true;
|
|
4402
4422
|
return this.pendingLoadedChildren.size === 0;
|
|
4403
4423
|
}
|
|
4424
|
+
cachePromise(value, callback) {
|
|
4425
|
+
if (this.lastPromise?.value === value) {
|
|
4426
|
+
return this.lastPromise.promise;
|
|
4427
|
+
}
|
|
4428
|
+
const promise = callback();
|
|
4429
|
+
this.lastPromise = { value, promise };
|
|
4430
|
+
return promise;
|
|
4431
|
+
}
|
|
4432
|
+
getPromise() {
|
|
4433
|
+
const currentValue = this.getCurrentValue();
|
|
4434
|
+
if (currentValue.$isLoaded) {
|
|
4435
|
+
return resolvedPromise(currentValue);
|
|
4436
|
+
}
|
|
4437
|
+
if (currentValue.$jazz.loadingState !== CoValueLoadingState.LOADING) {
|
|
4438
|
+
const error = this.getError();
|
|
4439
|
+
return rejectedPromise(
|
|
4440
|
+
new Error(error?.toString() ?? "Unknown error", {
|
|
4441
|
+
cause: this.callerStack
|
|
4442
|
+
})
|
|
4443
|
+
);
|
|
4444
|
+
}
|
|
4445
|
+
return this.cachePromise(currentValue, () => {
|
|
4446
|
+
return new Promise((resolve, reject) => {
|
|
4447
|
+
const unsubscribe = this.subscribe(() => {
|
|
4448
|
+
const currentValue2 = this.getCurrentValue();
|
|
4449
|
+
if (currentValue2.$jazz.loadingState === CoValueLoadingState.LOADING) {
|
|
4450
|
+
return;
|
|
4451
|
+
}
|
|
4452
|
+
if (currentValue2.$isLoaded) {
|
|
4453
|
+
resolve(currentValue2);
|
|
4454
|
+
} else {
|
|
4455
|
+
reject(
|
|
4456
|
+
new Error(this.getError()?.toString() ?? "Unknown error", {
|
|
4457
|
+
cause: this.callerStack
|
|
4458
|
+
})
|
|
4459
|
+
);
|
|
4460
|
+
}
|
|
4461
|
+
unsubscribe();
|
|
4462
|
+
});
|
|
4463
|
+
});
|
|
4464
|
+
});
|
|
4465
|
+
}
|
|
4404
4466
|
getUnloadedValue(reason) {
|
|
4405
4467
|
if (this.unloadedValue?.$jazz.loadingState === reason) {
|
|
4406
4468
|
return this.unloadedValue;
|
|
@@ -4451,14 +4513,16 @@ var SubscriptionScope = class _SubscriptionScope {
|
|
|
4451
4513
|
}
|
|
4452
4514
|
return result;
|
|
4453
4515
|
}
|
|
4454
|
-
|
|
4455
|
-
let error;
|
|
4516
|
+
getError() {
|
|
4456
4517
|
if (this.value.type === CoValueLoadingState.UNAUTHORIZED || this.value.type === CoValueLoadingState.UNAVAILABLE) {
|
|
4457
|
-
|
|
4518
|
+
return this.value;
|
|
4458
4519
|
}
|
|
4459
4520
|
if (this.errorFromChildren) {
|
|
4460
|
-
|
|
4521
|
+
return this.errorFromChildren;
|
|
4461
4522
|
}
|
|
4523
|
+
}
|
|
4524
|
+
logError() {
|
|
4525
|
+
const error = this.getError();
|
|
4462
4526
|
if (!error || this.lastErrorLogged === error) {
|
|
4463
4527
|
return;
|
|
4464
4528
|
}
|
|
@@ -4489,14 +4553,37 @@ var SubscriptionScope = class _SubscriptionScope {
|
|
|
4489
4553
|
}
|
|
4490
4554
|
this.dirty = false;
|
|
4491
4555
|
}
|
|
4556
|
+
/**
|
|
4557
|
+
* Subscribe to subscriber count changes
|
|
4558
|
+
* Callback receives the total number of subscribers
|
|
4559
|
+
* Returns an unsubscribe function
|
|
4560
|
+
*/
|
|
4561
|
+
onSubscriberChange(callback) {
|
|
4562
|
+
this.subscriberChangeCallbacks.add(callback);
|
|
4563
|
+
return () => {
|
|
4564
|
+
this.subscriberChangeCallbacks.delete(callback);
|
|
4565
|
+
};
|
|
4566
|
+
}
|
|
4567
|
+
notifySubscriberChange() {
|
|
4568
|
+
const count = this.subscribers.size;
|
|
4569
|
+
this.subscriberChangeCallbacks.forEach((callback) => {
|
|
4570
|
+
callback(count);
|
|
4571
|
+
});
|
|
4572
|
+
}
|
|
4492
4573
|
subscribe(listener) {
|
|
4493
4574
|
this.subscribers.add(listener);
|
|
4575
|
+
this.notifySubscriberChange();
|
|
4494
4576
|
return () => {
|
|
4495
4577
|
this.subscribers.delete(listener);
|
|
4578
|
+
this.notifySubscriberChange();
|
|
4496
4579
|
};
|
|
4497
4580
|
}
|
|
4498
4581
|
setListener(listener) {
|
|
4582
|
+
const hadListener = this.subscribers.has(listener);
|
|
4499
4583
|
this.subscribers.add(listener);
|
|
4584
|
+
if (!hadListener) {
|
|
4585
|
+
this.notifySubscriberChange();
|
|
4586
|
+
}
|
|
4500
4587
|
this.triggerUpdate();
|
|
4501
4588
|
}
|
|
4502
4589
|
subscribeToKey(key) {
|
|
@@ -4765,7 +4852,12 @@ var SubscriptionScope = class _SubscriptionScope {
|
|
|
4765
4852
|
destroy() {
|
|
4766
4853
|
this.closed = true;
|
|
4767
4854
|
this.subscription.unsubscribe();
|
|
4855
|
+
const hadSubscribers = this.subscribers.size > 0;
|
|
4768
4856
|
this.subscribers.clear();
|
|
4857
|
+
if (hadSubscribers) {
|
|
4858
|
+
this.notifySubscriberChange();
|
|
4859
|
+
}
|
|
4860
|
+
this.subscriberChangeCallbacks.clear();
|
|
4769
4861
|
this.childNodes.forEach((child) => child.destroy());
|
|
4770
4862
|
}
|
|
4771
4863
|
};
|
|
@@ -6381,6 +6473,177 @@ var InMemoryKVStore = class {
|
|
|
6381
6473
|
}
|
|
6382
6474
|
};
|
|
6383
6475
|
|
|
6476
|
+
// src/tools/subscribe/SubscriptionCache.ts
|
|
6477
|
+
var SubscriptionCache = class {
|
|
6478
|
+
constructor(cleanupTimeout = 5e3) {
|
|
6479
|
+
this.cache = /* @__PURE__ */ new Map();
|
|
6480
|
+
this.cleanupTimeout = cleanupTimeout;
|
|
6481
|
+
}
|
|
6482
|
+
/**
|
|
6483
|
+
* Get the inner set for a given id (read-only access)
|
|
6484
|
+
*/
|
|
6485
|
+
getIdSet(id) {
|
|
6486
|
+
return this.cache.get(id);
|
|
6487
|
+
}
|
|
6488
|
+
/**
|
|
6489
|
+
* Get the inner set for a given id, creating it if it doesn't exist
|
|
6490
|
+
*/
|
|
6491
|
+
getIdSetOrCreate(id) {
|
|
6492
|
+
let idSet = this.cache.get(id);
|
|
6493
|
+
if (!idSet) {
|
|
6494
|
+
idSet = /* @__PURE__ */ new Set();
|
|
6495
|
+
this.cache.set(id, idSet);
|
|
6496
|
+
}
|
|
6497
|
+
return idSet;
|
|
6498
|
+
}
|
|
6499
|
+
/**
|
|
6500
|
+
* Check if an entry matches the provided parameters
|
|
6501
|
+
*/
|
|
6502
|
+
matchesEntry(entry, schema, resolve, branch) {
|
|
6503
|
+
if (entry.schema !== schema) {
|
|
6504
|
+
return false;
|
|
6505
|
+
}
|
|
6506
|
+
if (!isEqualRefsToResolve(entry.resolve, resolve)) {
|
|
6507
|
+
return false;
|
|
6508
|
+
}
|
|
6509
|
+
const branchName = branch?.name;
|
|
6510
|
+
if (entry.branch?.name !== branchName) {
|
|
6511
|
+
return false;
|
|
6512
|
+
}
|
|
6513
|
+
const branchOwnerId = branch?.owner?.$jazz.id;
|
|
6514
|
+
if (entry.branch?.owner?.$jazz.id !== branchOwnerId) {
|
|
6515
|
+
return false;
|
|
6516
|
+
}
|
|
6517
|
+
return true;
|
|
6518
|
+
}
|
|
6519
|
+
/**
|
|
6520
|
+
* Find a matching cache entry by comparing against entry properties
|
|
6521
|
+
* Uses id-based nesting to quickly filter candidates
|
|
6522
|
+
*/
|
|
6523
|
+
findMatchingEntry(schema, id, resolve, branch) {
|
|
6524
|
+
const idSet = this.getIdSet(id);
|
|
6525
|
+
if (!idSet) {
|
|
6526
|
+
return void 0;
|
|
6527
|
+
}
|
|
6528
|
+
for (const entry of idSet) {
|
|
6529
|
+
if (this.matchesEntry(entry, schema, resolve, branch)) {
|
|
6530
|
+
return entry;
|
|
6531
|
+
}
|
|
6532
|
+
}
|
|
6533
|
+
return void 0;
|
|
6534
|
+
}
|
|
6535
|
+
/**
|
|
6536
|
+
* Handle subscriber count changes from SubscriptionScope
|
|
6537
|
+
*/
|
|
6538
|
+
handleSubscriberChange(entry, count) {
|
|
6539
|
+
entry.subscriberCount = count;
|
|
6540
|
+
if (count === 0) {
|
|
6541
|
+
this.scheduleCleanup(entry);
|
|
6542
|
+
} else {
|
|
6543
|
+
this.cancelCleanup(entry);
|
|
6544
|
+
}
|
|
6545
|
+
}
|
|
6546
|
+
/**
|
|
6547
|
+
* Schedule cleanup timeout for an entry
|
|
6548
|
+
*/
|
|
6549
|
+
scheduleCleanup(entry) {
|
|
6550
|
+
this.cancelCleanup(entry);
|
|
6551
|
+
entry.cleanupTimeoutId = setTimeout(() => {
|
|
6552
|
+
this.destroyEntry(entry);
|
|
6553
|
+
}, this.cleanupTimeout);
|
|
6554
|
+
}
|
|
6555
|
+
/**
|
|
6556
|
+
* Cancel pending cleanup timeout for an entry
|
|
6557
|
+
*/
|
|
6558
|
+
cancelCleanup(entry) {
|
|
6559
|
+
if (entry.cleanupTimeoutId !== void 0) {
|
|
6560
|
+
clearTimeout(entry.cleanupTimeoutId);
|
|
6561
|
+
entry.cleanupTimeoutId = void 0;
|
|
6562
|
+
}
|
|
6563
|
+
}
|
|
6564
|
+
/**
|
|
6565
|
+
* Destroy a cache entry and its SubscriptionScope
|
|
6566
|
+
*/
|
|
6567
|
+
destroyEntry(entry) {
|
|
6568
|
+
this.cancelCleanup(entry);
|
|
6569
|
+
entry.unsubscribeFromScope();
|
|
6570
|
+
try {
|
|
6571
|
+
entry.subscriptionScope.destroy();
|
|
6572
|
+
} catch (error) {
|
|
6573
|
+
console.error("Error destroying SubscriptionScope:", error);
|
|
6574
|
+
}
|
|
6575
|
+
const id = entry.subscriptionScope.id;
|
|
6576
|
+
const idSet = this.getIdSet(id);
|
|
6577
|
+
if (idSet) {
|
|
6578
|
+
idSet.delete(entry);
|
|
6579
|
+
if (idSet.size === 0) {
|
|
6580
|
+
this.cache.delete(id);
|
|
6581
|
+
}
|
|
6582
|
+
}
|
|
6583
|
+
}
|
|
6584
|
+
/**
|
|
6585
|
+
* Get or create a SubscriptionScope from the cache
|
|
6586
|
+
*/
|
|
6587
|
+
getOrCreate(node, schema, id, resolve, skipRetry, bestEffortResolution, branch) {
|
|
6588
|
+
if (!id) {
|
|
6589
|
+
throw new Error("Cannot create subscription with undefined or null id");
|
|
6590
|
+
}
|
|
6591
|
+
const matchingEntry = this.findMatchingEntry(schema, id, resolve, branch);
|
|
6592
|
+
if (matchingEntry) {
|
|
6593
|
+
this.cancelCleanup(matchingEntry);
|
|
6594
|
+
return matchingEntry.subscriptionScope;
|
|
6595
|
+
}
|
|
6596
|
+
const refEncoded = {
|
|
6597
|
+
ref: coValueClassFromCoValueClassOrSchema(schema),
|
|
6598
|
+
optional: true
|
|
6599
|
+
};
|
|
6600
|
+
const subscriptionScope = new SubscriptionScope(
|
|
6601
|
+
node,
|
|
6602
|
+
// @ts-expect-error the SubscriptionScope is too generic for TS to infer its instances are CoValues
|
|
6603
|
+
resolve,
|
|
6604
|
+
id,
|
|
6605
|
+
refEncoded,
|
|
6606
|
+
skipRetry ?? false,
|
|
6607
|
+
bestEffortResolution ?? false,
|
|
6608
|
+
branch
|
|
6609
|
+
);
|
|
6610
|
+
const handleSubscriberChange = (count) => {
|
|
6611
|
+
const idSet2 = this.getIdSet(id);
|
|
6612
|
+
if (idSet2 && idSet2.has(entry)) {
|
|
6613
|
+
this.handleSubscriberChange(entry, count);
|
|
6614
|
+
}
|
|
6615
|
+
};
|
|
6616
|
+
const entry = {
|
|
6617
|
+
subscriptionScope,
|
|
6618
|
+
schema,
|
|
6619
|
+
resolve,
|
|
6620
|
+
branch,
|
|
6621
|
+
subscriberCount: subscriptionScope.subscribers.size,
|
|
6622
|
+
unsubscribeFromScope: subscriptionScope.onSubscriberChange(
|
|
6623
|
+
handleSubscriberChange
|
|
6624
|
+
)
|
|
6625
|
+
};
|
|
6626
|
+
const idSet = this.getIdSetOrCreate(id);
|
|
6627
|
+
idSet.add(entry);
|
|
6628
|
+
return subscriptionScope;
|
|
6629
|
+
}
|
|
6630
|
+
/**
|
|
6631
|
+
* Clear all cache entries and destroy all SubscriptionScope instances
|
|
6632
|
+
*/
|
|
6633
|
+
clear() {
|
|
6634
|
+
const entriesToDestroy = [];
|
|
6635
|
+
for (const idSet of this.cache.values()) {
|
|
6636
|
+
for (const entry of idSet) {
|
|
6637
|
+
entriesToDestroy.push(entry);
|
|
6638
|
+
}
|
|
6639
|
+
}
|
|
6640
|
+
for (const entry of entriesToDestroy) {
|
|
6641
|
+
this.destroyEntry(entry);
|
|
6642
|
+
}
|
|
6643
|
+
this.cache.clear();
|
|
6644
|
+
}
|
|
6645
|
+
};
|
|
6646
|
+
|
|
6384
6647
|
// src/tools/implementation/ContextManager.ts
|
|
6385
6648
|
function getAnonymousFallback() {
|
|
6386
6649
|
const context = createAnonymousJazzContext({
|
|
@@ -6414,6 +6677,7 @@ var JazzContextManager = class {
|
|
|
6414
6677
|
return;
|
|
6415
6678
|
}
|
|
6416
6679
|
this.authenticatingAccountID = null;
|
|
6680
|
+
this.subscriptionCache.clear();
|
|
6417
6681
|
await this.props.onLogOut?.();
|
|
6418
6682
|
if (this.props.logOutReplacement) {
|
|
6419
6683
|
await this.props.logOutReplacement();
|
|
@@ -6511,6 +6775,7 @@ var JazzContextManager = class {
|
|
|
6511
6775
|
};
|
|
6512
6776
|
KvStoreContext.getInstance().initialize(this.getKvStore());
|
|
6513
6777
|
this.authSecretStorage = new AuthSecretStorage(opts?.authSecretStorageKey);
|
|
6778
|
+
this.subscriptionCache = new SubscriptionCache();
|
|
6514
6779
|
if (opts?.useAnonymousFallback) {
|
|
6515
6780
|
this.value = getAnonymousFallback();
|
|
6516
6781
|
}
|
|
@@ -6539,6 +6804,7 @@ var JazzContextManager = class {
|
|
|
6539
6804
|
throw new Error("Not implemented");
|
|
6540
6805
|
}
|
|
6541
6806
|
async updateContext(props, context, authProps) {
|
|
6807
|
+
this.subscriptionCache.clear();
|
|
6542
6808
|
if (!this.keepContextOpen) {
|
|
6543
6809
|
this.context?.done();
|
|
6544
6810
|
}
|
|
@@ -6576,6 +6842,9 @@ var JazzContextManager = class {
|
|
|
6576
6842
|
getAuthenticatingAccountID() {
|
|
6577
6843
|
return this.authenticatingAccountID;
|
|
6578
6844
|
}
|
|
6845
|
+
getSubscriptionScopeCache() {
|
|
6846
|
+
return this.subscriptionCache;
|
|
6847
|
+
}
|
|
6579
6848
|
async handleAnonymousAccountMigration(prevContext) {
|
|
6580
6849
|
if (!this.props) {
|
|
6581
6850
|
throw new Error("Props required");
|
|
@@ -7129,4 +7398,4 @@ export {
|
|
|
7129
7398
|
JazzContextManager
|
|
7130
7399
|
};
|
|
7131
7400
|
/* istanbul ignore file -- @preserve */
|
|
7132
|
-
//# sourceMappingURL=chunk-
|
|
7401
|
+
//# sourceMappingURL=chunk-HX5S6W5E.js.map
|