jazz-tools 0.8.44 → 0.8.45
Sign up to get free protection for your applications and to get access to all the features.
- package/.turbo/turbo-build.log +16 -10
- package/CHANGELOG.md +12 -0
- package/dist/chunk-5WLKIDKU.js +2844 -0
- package/dist/chunk-5WLKIDKU.js.map +1 -0
- package/dist/index.native.js +63 -0
- package/dist/index.native.js.map +1 -0
- package/dist/index.web.js +61 -0
- package/dist/index.web.js.map +1 -0
- package/package.json +9 -12
- package/src/coValues/account.ts +21 -9
- package/src/coValues/coFeed.ts +4 -3
- package/src/coValues/coList.ts +8 -5
- package/src/coValues/coMap.ts +6 -3
- package/src/coValues/deepLoading.ts +6 -12
- package/src/coValues/extensions/imageDef.ts +3 -1
- package/src/coValues/group.ts +8 -11
- package/src/coValues/inbox.ts +377 -0
- package/src/coValues/interfaces.ts +9 -6
- package/src/coValues/profile.ts +11 -0
- package/src/coValues/registeredSchemas.ts +12 -0
- package/src/exports.ts +21 -15
- package/src/implementation/anonymousJazzAgent.ts +6 -0
- package/src/implementation/createContext.ts +6 -7
- package/src/implementation/refs.ts +1 -1
- package/src/implementation/subscriptionScope.ts +1 -1
- package/src/index.native.ts +0 -1
- package/src/internal.ts +1 -9
- package/src/tests/account.test.ts +2 -2
- package/src/tests/coFeed.test.ts +0 -9
- package/src/tests/coMap.test.ts +2 -2
- package/src/tests/groupsAndAccounts.test.ts +1 -1
- package/src/tests/inbox.test.ts +256 -0
- package/src/tests/schemaUnion.test.ts +1 -1
- package/src/tests/utils.ts +14 -0
- package/tsup.config.ts +13 -0
- package/dist/native/coValues/account.js +0 -221
- package/dist/native/coValues/account.js.map +0 -1
- package/dist/native/coValues/coFeed.js +0 -571
- package/dist/native/coValues/coFeed.js.map +0 -1
- package/dist/native/coValues/coList.js +0 -404
- package/dist/native/coValues/coList.js.map +0 -1
- package/dist/native/coValues/coMap.js +0 -537
- package/dist/native/coValues/coMap.js.map +0 -1
- package/dist/native/coValues/deepLoading.js +0 -63
- package/dist/native/coValues/deepLoading.js.map +0 -1
- package/dist/native/coValues/extensions/imageDef.js +0 -42
- package/dist/native/coValues/extensions/imageDef.js.map +0 -1
- package/dist/native/coValues/group.js +0 -136
- package/dist/native/coValues/group.js.map +0 -1
- package/dist/native/coValues/interfaces.js +0 -135
- package/dist/native/coValues/interfaces.js.map +0 -1
- package/dist/native/coValues/schemaUnion.js +0 -89
- package/dist/native/coValues/schemaUnion.js.map +0 -1
- package/dist/native/exports.js +0 -5
- package/dist/native/exports.js.map +0 -1
- package/dist/native/implementation/createContext.js +0 -157
- package/dist/native/implementation/createContext.js.map +0 -1
- package/dist/native/implementation/devtoolsFormatters.js +0 -95
- package/dist/native/implementation/devtoolsFormatters.js.map +0 -1
- package/dist/native/implementation/errors.js +0 -2
- package/dist/native/implementation/errors.js.map +0 -1
- package/dist/native/implementation/inspect.js +0 -2
- package/dist/native/implementation/inspect.js.map +0 -1
- package/dist/native/implementation/refs.js +0 -115
- package/dist/native/implementation/refs.js.map +0 -1
- package/dist/native/implementation/schema.js +0 -96
- package/dist/native/implementation/schema.js.map +0 -1
- package/dist/native/implementation/subscriptionScope.js +0 -91
- package/dist/native/implementation/subscriptionScope.js.map +0 -1
- package/dist/native/implementation/symbols.js +0 -4
- package/dist/native/implementation/symbols.js.map +0 -1
- package/dist/native/index.native.js +0 -3
- package/dist/native/index.native.js.map +0 -1
- package/dist/native/internal.js +0 -18
- package/dist/native/internal.js.map +0 -1
- package/dist/native/lib/cache.js +0 -13
- package/dist/native/lib/cache.js.map +0 -1
- package/dist/native/lib/cache.test.js +0 -52
- package/dist/native/lib/cache.test.js.map +0 -1
- package/dist/web/coValues/account.js +0 -221
- package/dist/web/coValues/account.js.map +0 -1
- package/dist/web/coValues/coFeed.js +0 -571
- package/dist/web/coValues/coFeed.js.map +0 -1
- package/dist/web/coValues/coList.js +0 -404
- package/dist/web/coValues/coList.js.map +0 -1
- package/dist/web/coValues/coMap.js +0 -537
- package/dist/web/coValues/coMap.js.map +0 -1
- package/dist/web/coValues/deepLoading.js +0 -63
- package/dist/web/coValues/deepLoading.js.map +0 -1
- package/dist/web/coValues/extensions/imageDef.js +0 -42
- package/dist/web/coValues/extensions/imageDef.js.map +0 -1
- package/dist/web/coValues/group.js +0 -136
- package/dist/web/coValues/group.js.map +0 -1
- package/dist/web/coValues/interfaces.js +0 -135
- package/dist/web/coValues/interfaces.js.map +0 -1
- package/dist/web/coValues/schemaUnion.js +0 -89
- package/dist/web/coValues/schemaUnion.js.map +0 -1
- package/dist/web/exports.js +0 -5
- package/dist/web/exports.js.map +0 -1
- package/dist/web/implementation/createContext.js +0 -157
- package/dist/web/implementation/createContext.js.map +0 -1
- package/dist/web/implementation/devtoolsFormatters.js +0 -95
- package/dist/web/implementation/devtoolsFormatters.js.map +0 -1
- package/dist/web/implementation/errors.js +0 -2
- package/dist/web/implementation/errors.js.map +0 -1
- package/dist/web/implementation/inspect.js +0 -2
- package/dist/web/implementation/inspect.js.map +0 -1
- package/dist/web/implementation/refs.js +0 -115
- package/dist/web/implementation/refs.js.map +0 -1
- package/dist/web/implementation/schema.js +0 -96
- package/dist/web/implementation/schema.js.map +0 -1
- package/dist/web/implementation/subscriptionScope.js +0 -91
- package/dist/web/implementation/subscriptionScope.js.map +0 -1
- package/dist/web/implementation/symbols.js +0 -4
- package/dist/web/implementation/symbols.js.map +0 -1
- package/dist/web/index.web.js +0 -3
- package/dist/web/index.web.js.map +0 -1
- package/dist/web/internal.js +0 -18
- package/dist/web/internal.js.map +0 -1
- package/dist/web/lib/cache.js +0 -13
- package/dist/web/lib/cache.js.map +0 -1
- package/dist/web/lib/cache.test.js +0 -52
- package/dist/web/lib/cache.test.js.map +0 -1
@@ -1,17 +1,18 @@
|
|
1
1
|
import type { CojsonInternalTypes, RawCoValue } from "cojson";
|
2
2
|
import { RawAccount } from "cojson";
|
3
|
+
import { AnonymousJazzAgent } from "../implementation/anonymousJazzAgent.js";
|
3
4
|
import type { DeeplyLoaded, DepthsIn } from "../internal.js";
|
4
5
|
import {
|
5
|
-
Account,
|
6
|
-
AnonymousJazzAgent,
|
7
|
-
Group,
|
8
6
|
Ref,
|
9
7
|
SubscriptionScope,
|
10
8
|
inspect,
|
11
9
|
subscriptionsScopes,
|
12
10
|
} from "../internal.js";
|
13
11
|
import { coValuesCache } from "../lib/cache.js";
|
12
|
+
import { type Account } from "./account.js";
|
14
13
|
import { fulfillsDepth } from "./deepLoading.js";
|
14
|
+
import { type Group } from "./group.js";
|
15
|
+
import { RegisteredSchemas } from "./registeredSchemas.js";
|
15
16
|
|
16
17
|
/** @category Abstract interfaces */
|
17
18
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
@@ -85,8 +86,8 @@ export class CoValueBase implements CoValue {
|
|
85
86
|
get _owner(): Account | Group {
|
86
87
|
const owner =
|
87
88
|
this._raw.group instanceof RawAccount
|
88
|
-
? Account.fromRaw(this._raw.group)
|
89
|
-
: Group.fromRaw(this._raw.group);
|
89
|
+
? RegisteredSchemas["Account"].fromRaw(this._raw.group)
|
90
|
+
: RegisteredSchemas["Group"].fromRaw(this._raw.group);
|
90
91
|
|
91
92
|
const subScope = subscriptionsScopes.get(this);
|
92
93
|
if (subScope) {
|
@@ -102,7 +103,9 @@ export class CoValueBase implements CoValue {
|
|
102
103
|
const rawAccount = this._raw.core.node.account;
|
103
104
|
|
104
105
|
if (rawAccount instanceof RawAccount) {
|
105
|
-
return coValuesCache.get(rawAccount, () =>
|
106
|
+
return coValuesCache.get(rawAccount, () =>
|
107
|
+
RegisteredSchemas["Account"].fromRaw(rawAccount),
|
108
|
+
);
|
106
109
|
}
|
107
110
|
|
108
111
|
return new AnonymousJazzAgent(this._raw.core.node);
|
@@ -0,0 +1,11 @@
|
|
1
|
+
import { CoID } from "cojson";
|
2
|
+
import { co } from "../internal.js";
|
3
|
+
import { CoMap } from "./coMap.js";
|
4
|
+
import { InboxInvite, InboxRoot } from "./inbox.js";
|
5
|
+
|
6
|
+
/** @category Identity & Permissions */
|
7
|
+
export class Profile extends CoMap {
|
8
|
+
name = co.string;
|
9
|
+
inbox = co.optional.json<CoID<InboxRoot>>();
|
10
|
+
inboxInvite = co.optional.json<InboxInvite>();
|
11
|
+
}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
import type { Account } from "./account.js";
|
2
|
+
import type { CoMap } from "./coMap.js";
|
3
|
+
import type { Group } from "./group.js";
|
4
|
+
|
5
|
+
/**
|
6
|
+
* Regisering schemas into this Record to avoid circular dependencies.
|
7
|
+
*/
|
8
|
+
export const RegisteredSchemas = {} as {
|
9
|
+
Account: typeof Account;
|
10
|
+
Group: typeof Group;
|
11
|
+
CoMap: typeof CoMap;
|
12
|
+
};
|
package/src/exports.ts
CHANGED
@@ -12,25 +12,31 @@ export type { CoValue, ID } from "./internal.js";
|
|
12
12
|
|
13
13
|
export { Encoders, co } from "./internal.js";
|
14
14
|
|
15
|
+
export {
|
16
|
+
Inbox,
|
17
|
+
InboxSender,
|
18
|
+
} from "./coValues/inbox.js";
|
19
|
+
|
15
20
|
export {
|
16
21
|
Account,
|
17
|
-
FileStream,
|
18
|
-
BinaryCoStream,
|
19
|
-
CoList,
|
20
|
-
CoMap,
|
21
|
-
CoFeed,
|
22
|
-
CoStream,
|
23
|
-
CoValueBase,
|
24
|
-
Group,
|
25
|
-
ImageDefinition,
|
26
|
-
Profile,
|
27
22
|
isControlledAccount,
|
28
|
-
SchemaUnion,
|
29
23
|
type AccountClass,
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
24
|
+
} from "./coValues/account.js";
|
25
|
+
export { Group } from "./coValues/group.js";
|
26
|
+
export {
|
27
|
+
CoStream,
|
28
|
+
CoFeed,
|
29
|
+
FileStream,
|
30
|
+
BinaryCoStream,
|
31
|
+
} from "./coValues/coFeed.js";
|
32
|
+
export { CoList } from "./coValues/coList.js";
|
33
|
+
export { CoMap, type CoMapInit } from "./coValues/coMap.js";
|
34
|
+
export { CoValueBase } from "./coValues/interfaces.js";
|
35
|
+
export { ImageDefinition } from "./coValues/extensions/imageDef.js";
|
36
|
+
export { Profile } from "./coValues/profile.js";
|
37
|
+
export { SchemaUnion } from "./coValues/schemaUnion.js";
|
38
|
+
|
39
|
+
export type { CoValueClass, DeeplyLoaded, DepthsIn } from "./internal.js";
|
34
40
|
|
35
41
|
export {
|
36
42
|
createCoValueObservable,
|
@@ -9,7 +9,10 @@ import {
|
|
9
9
|
RawAccountID,
|
10
10
|
SessionID,
|
11
11
|
} from "cojson";
|
12
|
-
import { Account, AccountClass
|
12
|
+
import { type Account, type AccountClass } from "../coValues/account.js";
|
13
|
+
import { RegisteredSchemas } from "../coValues/registeredSchemas.js";
|
14
|
+
import type { ID } from "../internal.js";
|
15
|
+
import { AnonymousJazzAgent } from "./anonymousJazzAgent.js";
|
13
16
|
|
14
17
|
export type Credentials = {
|
15
18
|
accountID: ID<Account>;
|
@@ -136,7 +139,8 @@ export async function createJazzContext<Acc extends Account>(
|
|
136
139
|
|
137
140
|
const { auth, sessionProvider, peersToLoadFrom, crypto } = options;
|
138
141
|
const AccountSchema =
|
139
|
-
options.AccountSchema ??
|
142
|
+
options.AccountSchema ??
|
143
|
+
(RegisteredSchemas["Account"] as unknown as AccountClass<Acc>);
|
140
144
|
let authResult: AuthResult;
|
141
145
|
try {
|
142
146
|
authResult = await auth.start(crypto);
|
@@ -243,11 +247,6 @@ export async function createJazzContext<Acc extends Account>(
|
|
243
247
|
}
|
244
248
|
}
|
245
249
|
|
246
|
-
export class AnonymousJazzAgent {
|
247
|
-
_type = "Anonymous" as const;
|
248
|
-
constructor(public node: LocalNode) {}
|
249
|
-
}
|
250
|
-
|
251
250
|
export async function createAnonymousJazzContext({
|
252
251
|
peersToLoadFrom,
|
253
252
|
crypto,
|
package/src/index.native.ts
CHANGED
package/src/internal.ts
CHANGED
@@ -2,21 +2,13 @@ export * from "./implementation/symbols.js";
|
|
2
2
|
export * from "./implementation/inspect.js";
|
3
3
|
export * from "./coValues/interfaces.js";
|
4
4
|
|
5
|
-
export * from "./coValues/coMap.js";
|
6
|
-
export * from "./coValues/account.js";
|
7
|
-
export * from "./coValues/coList.js";
|
8
|
-
export * from "./coValues/coFeed.js";
|
9
|
-
export * from "./coValues/schemaUnion.js";
|
10
|
-
export * from "./coValues/group.js";
|
11
|
-
|
12
5
|
export * from "./implementation/errors.js";
|
6
|
+
export * from "./implementation/anonymousJazzAgent.js";
|
13
7
|
export * from "./implementation/refs.js";
|
14
8
|
export * from "./implementation/schema.js";
|
15
9
|
export * from "./implementation/subscriptionScope.js";
|
16
10
|
export * from "./coValues/deepLoading.js";
|
17
11
|
|
18
|
-
export * from "./coValues/extensions/imageDef.js";
|
19
|
-
|
20
12
|
export * from "./implementation/createContext.js";
|
21
13
|
|
22
14
|
import "./implementation/devtoolsFormatters.js";
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { expect, test } from "vitest";
|
2
|
-
import { CoMap, co } from "../
|
3
|
-
import { setupTwoNodes } from "./utils";
|
2
|
+
import { CoMap, co } from "../exports.js";
|
3
|
+
import { setupTwoNodes } from "./utils.js";
|
4
4
|
|
5
5
|
test("waitForAllCoValuesSync should resolve when all the values are synced", async () => {
|
6
6
|
class TestMap extends CoMap {
|
package/src/tests/coFeed.test.ts
CHANGED
@@ -192,15 +192,6 @@ describe("CoFeed resolution", async () => {
|
|
192
192
|
const queue = new cojsonInternals.Channel();
|
193
193
|
|
194
194
|
TestStream.subscribe(stream.id, meOnSecondPeer, [], (subscribedStream) => {
|
195
|
-
console.log("subscribedStream[me.id]", subscribedStream[me.id]);
|
196
|
-
console.log(
|
197
|
-
"subscribedStream[me.id]?.value?.[me.id]?.value",
|
198
|
-
subscribedStream[me.id]?.value?.[me.id]?.value,
|
199
|
-
);
|
200
|
-
console.log(
|
201
|
-
"subscribedStream[me.id]?.value?.[me.id]?.value?.[me.id]?.value",
|
202
|
-
subscribedStream[me.id]?.value?.[me.id]?.value?.[me.id]?.value,
|
203
|
-
);
|
204
195
|
void queue.push(subscribedStream);
|
205
196
|
});
|
206
197
|
|
package/src/tests/coMap.test.ts
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
import { connectedPeers } from "cojson/src/streamUtils.ts";
|
2
2
|
import { describe, expect, expectTypeOf, test } from "vitest";
|
3
|
+
import { Group, randomSessionProvider } from "../exports.js";
|
3
4
|
import {
|
4
5
|
Account,
|
5
6
|
CoMap,
|
@@ -11,8 +12,7 @@ import {
|
|
11
12
|
fixedCredentialsAuth,
|
12
13
|
isControlledAccount,
|
13
14
|
} from "../index.web.js";
|
14
|
-
import {
|
15
|
-
import { loadCoValueOrFail, setupTwoNodes } from "./utils.js";
|
15
|
+
import { setupTwoNodes } from "./utils.js";
|
16
16
|
|
17
17
|
const Crypto = await WasmCrypto.create();
|
18
18
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import { RawGroup } from "cojson";
|
2
2
|
import { describe, expect, test } from "vitest";
|
3
3
|
import { Account, CoMap, Group, WasmCrypto, co } from "../index.web.js";
|
4
|
-
import { setupTwoNodes
|
4
|
+
import { setupTwoNodes } from "./utils.js";
|
5
5
|
|
6
6
|
const Crypto = await WasmCrypto.create();
|
7
7
|
|
@@ -0,0 +1,256 @@
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
2
|
+
import { CoMap } from "../coValues/coMap";
|
3
|
+
import { Group } from "../coValues/group";
|
4
|
+
import { Inbox, InboxSender } from "../coValues/inbox";
|
5
|
+
import { co } from "../internal";
|
6
|
+
import { setupTwoNodes, waitFor } from "./utils";
|
7
|
+
|
8
|
+
class Message extends CoMap {
|
9
|
+
text = co.string;
|
10
|
+
}
|
11
|
+
|
12
|
+
describe("Inbox", () => {
|
13
|
+
it("should create inbox and allow message exchange between accounts", async () => {
|
14
|
+
const { clientAccount: sender, serverAccount: receiver } =
|
15
|
+
await setupTwoNodes();
|
16
|
+
|
17
|
+
const receiverInbox = await Inbox.load(receiver);
|
18
|
+
|
19
|
+
// Create a message from sender
|
20
|
+
const message = Message.create(
|
21
|
+
{ text: "Hello" },
|
22
|
+
{
|
23
|
+
owner: Group.create({ owner: sender }),
|
24
|
+
},
|
25
|
+
);
|
26
|
+
|
27
|
+
// Setup inbox sender
|
28
|
+
const inboxSender = await InboxSender.load(receiver.id, sender);
|
29
|
+
inboxSender.sendMessage(message);
|
30
|
+
|
31
|
+
// Track received messages
|
32
|
+
const receivedMessages: Message[] = [];
|
33
|
+
let senderAccountID: unknown = undefined;
|
34
|
+
|
35
|
+
// Subscribe to inbox messages
|
36
|
+
const unsubscribe = receiverInbox.subscribe(
|
37
|
+
Message,
|
38
|
+
async (message, id) => {
|
39
|
+
senderAccountID = id;
|
40
|
+
receivedMessages.push(message);
|
41
|
+
},
|
42
|
+
);
|
43
|
+
|
44
|
+
// Wait for message to be received
|
45
|
+
await waitFor(() => receivedMessages.length === 1);
|
46
|
+
|
47
|
+
expect(receivedMessages.length).toBe(1);
|
48
|
+
expect(receivedMessages[0]?.text).toBe("Hello");
|
49
|
+
expect(senderAccountID).toBe(sender.id);
|
50
|
+
|
51
|
+
unsubscribe();
|
52
|
+
});
|
53
|
+
|
54
|
+
it("should return the result of the message", async () => {
|
55
|
+
const { clientAccount: sender, serverAccount: receiver } =
|
56
|
+
await setupTwoNodes();
|
57
|
+
|
58
|
+
const receiverInbox = await Inbox.load(receiver);
|
59
|
+
|
60
|
+
// Create a message from sender
|
61
|
+
const message = Message.create(
|
62
|
+
{ text: "Hello" },
|
63
|
+
{
|
64
|
+
owner: Group.create({ owner: sender }),
|
65
|
+
},
|
66
|
+
);
|
67
|
+
|
68
|
+
const unsubscribe = receiverInbox.subscribe(Message, async (message) => {
|
69
|
+
return Message.create(
|
70
|
+
{ text: "Responded from the inbox" },
|
71
|
+
{ owner: message._owner },
|
72
|
+
);
|
73
|
+
});
|
74
|
+
|
75
|
+
// Setup inbox sender
|
76
|
+
const inboxSender = await InboxSender.load<Message, Message>(
|
77
|
+
receiver.id,
|
78
|
+
sender,
|
79
|
+
);
|
80
|
+
const resultId = await inboxSender.sendMessage(message);
|
81
|
+
|
82
|
+
const result = await Message.load(resultId, receiver, {});
|
83
|
+
expect(result?.text).toBe("Responded from the inbox");
|
84
|
+
|
85
|
+
unsubscribe();
|
86
|
+
});
|
87
|
+
|
88
|
+
it("should return the undefined if the subscription returns undefined", async () => {
|
89
|
+
const { clientAccount: sender, serverAccount: receiver } =
|
90
|
+
await setupTwoNodes();
|
91
|
+
|
92
|
+
const receiverInbox = await Inbox.load(receiver);
|
93
|
+
|
94
|
+
// Create a message from sender
|
95
|
+
const message = Message.create(
|
96
|
+
{ text: "Hello" },
|
97
|
+
{
|
98
|
+
owner: Group.create({ owner: sender }),
|
99
|
+
},
|
100
|
+
);
|
101
|
+
|
102
|
+
const unsubscribe = receiverInbox.subscribe(Message, async (message) => {});
|
103
|
+
|
104
|
+
// Setup inbox sender
|
105
|
+
const inboxSender = await InboxSender.load<Message>(receiver.id, sender);
|
106
|
+
const result = await inboxSender.sendMessage(message);
|
107
|
+
|
108
|
+
expect(result).toBeUndefined();
|
109
|
+
|
110
|
+
unsubscribe();
|
111
|
+
});
|
112
|
+
|
113
|
+
it("should reject if the subscription throws an error", async () => {
|
114
|
+
const { clientAccount: sender, serverAccount: receiver } =
|
115
|
+
await setupTwoNodes();
|
116
|
+
|
117
|
+
const receiverInbox = await Inbox.load(receiver);
|
118
|
+
|
119
|
+
// Create a message from sender
|
120
|
+
const message = Message.create(
|
121
|
+
{ text: "Hello" },
|
122
|
+
{
|
123
|
+
owner: Group.create({ owner: sender }),
|
124
|
+
},
|
125
|
+
);
|
126
|
+
|
127
|
+
const unsubscribe = receiverInbox.subscribe(Message, async () => {
|
128
|
+
return Promise.reject(new Error("Failed"));
|
129
|
+
});
|
130
|
+
|
131
|
+
// Setup inbox sender
|
132
|
+
const inboxSender = await InboxSender.load<Message>(receiver.id, sender);
|
133
|
+
|
134
|
+
await expect(inboxSender.sendMessage(message)).rejects.toThrow(
|
135
|
+
"Error: Failed",
|
136
|
+
);
|
137
|
+
|
138
|
+
unsubscribe();
|
139
|
+
});
|
140
|
+
|
141
|
+
it("should mark messages as processed", async () => {
|
142
|
+
const { clientAccount: sender, serverAccount: receiver } =
|
143
|
+
await setupTwoNodes();
|
144
|
+
|
145
|
+
const receiverInbox = await Inbox.load(receiver);
|
146
|
+
|
147
|
+
// Create a message from sender
|
148
|
+
const message = Message.create(
|
149
|
+
{ text: "Hello" },
|
150
|
+
{
|
151
|
+
owner: Group.create({ owner: sender }),
|
152
|
+
},
|
153
|
+
);
|
154
|
+
|
155
|
+
// Setup inbox sender
|
156
|
+
const inboxSender = await InboxSender.load(receiver.id, sender);
|
157
|
+
inboxSender.sendMessage(message);
|
158
|
+
|
159
|
+
// Track received messages
|
160
|
+
const receivedMessages: Message[] = [];
|
161
|
+
|
162
|
+
// Subscribe to inbox messages
|
163
|
+
const unsubscribe = receiverInbox.subscribe(Message, async (message) => {
|
164
|
+
receivedMessages.push(message);
|
165
|
+
});
|
166
|
+
|
167
|
+
// Wait for message to be received
|
168
|
+
await waitFor(() => receivedMessages.length === 1);
|
169
|
+
|
170
|
+
inboxSender.sendMessage(message);
|
171
|
+
|
172
|
+
await waitFor(() => receivedMessages.length === 2);
|
173
|
+
|
174
|
+
expect(receivedMessages.length).toBe(2);
|
175
|
+
expect(receivedMessages[0]?.text).toBe("Hello");
|
176
|
+
expect(receivedMessages[1]?.text).toBe("Hello");
|
177
|
+
|
178
|
+
unsubscribe();
|
179
|
+
});
|
180
|
+
|
181
|
+
it("should unsubscribe correctly", async () => {
|
182
|
+
const { clientAccount: sender, serverAccount: receiver } =
|
183
|
+
await setupTwoNodes();
|
184
|
+
|
185
|
+
const receiverInbox = await Inbox.load(receiver);
|
186
|
+
|
187
|
+
// Create a message from sender
|
188
|
+
const message = Message.create(
|
189
|
+
{ text: "Hello" },
|
190
|
+
{
|
191
|
+
owner: Group.create({ owner: sender }),
|
192
|
+
},
|
193
|
+
);
|
194
|
+
|
195
|
+
// Setup inbox sender
|
196
|
+
const inboxSender = await InboxSender.load(receiver.id, sender);
|
197
|
+
inboxSender.sendMessage(message);
|
198
|
+
|
199
|
+
// Track received messages
|
200
|
+
const receivedMessages: Message[] = [];
|
201
|
+
|
202
|
+
// Subscribe to inbox messages
|
203
|
+
const unsubscribe = receiverInbox.subscribe(Message, async (message) => {
|
204
|
+
receivedMessages.push(message);
|
205
|
+
});
|
206
|
+
|
207
|
+
// Wait for message to be received
|
208
|
+
await waitFor(() => receivedMessages.length === 1);
|
209
|
+
|
210
|
+
unsubscribe();
|
211
|
+
|
212
|
+
inboxSender.sendMessage(message);
|
213
|
+
|
214
|
+
await new Promise((resolve) => setTimeout(resolve, 200));
|
215
|
+
|
216
|
+
expect(receivedMessages.length).toBe(1);
|
217
|
+
expect(receivedMessages[0]?.text).toBe("Hello");
|
218
|
+
});
|
219
|
+
|
220
|
+
it("should retry failed messages", async () => {
|
221
|
+
const { clientAccount: sender, serverAccount: receiver } =
|
222
|
+
await setupTwoNodes();
|
223
|
+
|
224
|
+
const receiverInbox = await Inbox.load(receiver);
|
225
|
+
|
226
|
+
// Create a message from sender
|
227
|
+
const message = Message.create(
|
228
|
+
{ text: "Hello" },
|
229
|
+
{
|
230
|
+
owner: Group.create({ owner: sender }),
|
231
|
+
},
|
232
|
+
);
|
233
|
+
|
234
|
+
// Setup inbox sender
|
235
|
+
const inboxSender = await InboxSender.load(receiver.id, sender);
|
236
|
+
const promise = inboxSender.sendMessage(message);
|
237
|
+
|
238
|
+
let failures = 0;
|
239
|
+
|
240
|
+
// Subscribe to inbox messages
|
241
|
+
const unsubscribe = receiverInbox.subscribe(
|
242
|
+
Message,
|
243
|
+
async () => {
|
244
|
+
failures++;
|
245
|
+
throw new Error("Failed");
|
246
|
+
},
|
247
|
+
{ retries: 2 },
|
248
|
+
);
|
249
|
+
|
250
|
+
await expect(promise).rejects.toThrow();
|
251
|
+
expect(failures).toBe(3);
|
252
|
+
const [failed] = Object.values(receiverInbox.failed.items).flat();
|
253
|
+
expect(failed?.value.errors.length).toBe(3);
|
254
|
+
unsubscribe();
|
255
|
+
});
|
256
|
+
});
|
package/src/tests/utils.ts
CHANGED
@@ -54,12 +54,26 @@ export async function setupTwoNodes() {
|
|
54
54
|
peersToLoadFrom: [serverAsPeer],
|
55
55
|
crypto: Crypto,
|
56
56
|
creationProps: { name: "Client" },
|
57
|
+
migration: async (rawAccount, _node, creationProps) => {
|
58
|
+
const account = new Account({
|
59
|
+
fromRaw: rawAccount,
|
60
|
+
});
|
61
|
+
|
62
|
+
await account.migrate?.(creationProps);
|
63
|
+
},
|
57
64
|
});
|
58
65
|
|
59
66
|
const server = await LocalNode.withNewlyCreatedAccount({
|
60
67
|
peersToLoadFrom: [clientAsPeer],
|
61
68
|
crypto: Crypto,
|
62
69
|
creationProps: { name: "Server" },
|
70
|
+
migration: async (rawAccount, _node, creationProps) => {
|
71
|
+
const account = new Account({
|
72
|
+
fromRaw: rawAccount,
|
73
|
+
});
|
74
|
+
|
75
|
+
await account.migrate?.(creationProps);
|
76
|
+
},
|
63
77
|
});
|
64
78
|
|
65
79
|
return {
|
package/tsup.config.ts
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
import { defineConfig } from "tsup";
|
2
|
+
|
3
|
+
export default defineConfig({
|
4
|
+
entry: {
|
5
|
+
"index.web": "src/index.web.ts",
|
6
|
+
"index.native": "src/index.native.ts",
|
7
|
+
},
|
8
|
+
format: ["esm"],
|
9
|
+
dts: false,
|
10
|
+
sourcemap: true,
|
11
|
+
clean: true,
|
12
|
+
minify: false,
|
13
|
+
});
|