diff --git a/.changeset/config.json b/.changeset/config.json index f94e063c..2b76bec2 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -11,7 +11,8 @@ "ignore": [ "@n1ru4l/example-client", "@n1ru4l/example-server", - "@n1ru4l/todo-example-client", - "@n1ru4l/todo-example-server" + "@n1ru4l/todo-example-server", + "@n1ru4l/todo-example-client-apollo", + "@n1ru4l/todo-example-client-relay" ] } diff --git a/.changeset/quick-spies-end.md b/.changeset/quick-spies-end.md new file mode 100644 index 00000000..3298eefe --- /dev/null +++ b/.changeset/quick-spies-end.md @@ -0,0 +1,6 @@ +--- +"@n1ru4l/graphql-live-query": minor +"@n1ru4l/in-memory-live-query-store": minor +--- + +rename triggerUpdate method to emit diff --git a/README.md b/README.md index 78498e9d..af68e606 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ Practical example: // somewhere inside a mutation resolver await db.users.push(createNewUser()); // all live queries that select Query.users must be updated. -liveQueryStore.triggerUpdate("Query.users"); +liveQueryStore.emit("Query.users"); ``` ### 2. How are the updates sent/applied to the client diff --git a/bob.config.js b/bob.config.js index 0a9ffe31..796ebbb5 100644 --- a/bob.config.js +++ b/bob.config.js @@ -3,7 +3,7 @@ module.exports = { ignore: [ "@n1ru4l/example-client", "@n1ru4l/example-server", - "@n1ru4l/todo-example-client", + "@n1ru4l/todo-example-client-relay", "@n1ru4l/todo-example-client-apollo", "@n1ru4l/todo-example-server", ], // ignored packages diff --git a/packages/example/server/src/main.ts b/packages/example/server/src/main.ts index 6b3f5e26..37c1052c 100644 --- a/packages/example/server/src/main.ts +++ b/packages/example/server/src/main.ts @@ -29,14 +29,14 @@ const server = app const socketServer = socketIO(server); const subscriptionPubSub = new PubSub(); -const liveQueryStore = new InMemoryLiveQueryStore({}); +const liveQueryStore = new InMemoryLiveQueryStore(); const userStore = new UserStore(); const messageStore = new MessageStore(); // lets add some new users randomly setInterval(() => { userStore.add(fakeData.createFakeUser()); - liveQueryStore.triggerUpdate("Query.users"); + liveQueryStore.emit("Query.users"); }, 10000).unref(); // lets add some new messages randomly @@ -46,7 +46,7 @@ setInterval(() => { if (user) { const newMessage = fakeData.createFakeMessage(user.id); messageStore.add(newMessage); - liveQueryStore.triggerUpdate("Query.messages"); + liveQueryStore.emit("Query.messages"); subscriptionPubSub.publish("onNewMessage", { messageId: newMessage.id }); } }, 100).unref(); @@ -58,7 +58,7 @@ setInterval(() => { const message = messageStore.getLast(); if (message) { message.content = fakeData.randomSentence(); - liveQueryStore.triggerUpdate("Query.messages"); + liveQueryStore.emit("Query.messages"); } } }, 2000).unref(); diff --git a/packages/graphql-live-query/src/LiveQueryStore.ts b/packages/graphql-live-query/src/LiveQueryStore.ts index ce174269..1f79c3c6 100644 --- a/packages/graphql-live-query/src/LiveQueryStore.ts +++ b/packages/graphql-live-query/src/LiveQueryStore.ts @@ -14,7 +14,7 @@ export type LiveQueryStoreRegisterParameter = { }; export abstract class LiveQueryStore { - abstract async triggerUpdate(identifier: string): Promise; + abstract emit(identifier: string): Promise; abstract register( params: LiveQueryStoreRegisterParameter ): UnsubscribeHandler; diff --git a/packages/in-memory-live-query-store/README.md b/packages/in-memory-live-query-store/README.md index 9a5791b6..1d53b1c8 100644 --- a/packages/in-memory-live-query-store/README.md +++ b/packages/in-memory-live-query-store/README.md @@ -47,7 +47,7 @@ const registration = inMemoryLiveQueryStore.register({ }); rootValue.todos[0].isComplete = true; -inMemoryLiveQueryStore.triggerUpdate(`Todo:1`); +inMemoryLiveQueryStore.emit(`Todo:1`); rootValue.todos.push({ id: "2", content: "Baz", isComplete: false }); -inMemoryLiveQueryStore.triggerUpdate(`Query.todos`); +inMemoryLiveQueryStore.emit(`Query.todos`); ``` diff --git a/packages/in-memory-live-query-store/src/InMemoryLiveQueryStore.ts b/packages/in-memory-live-query-store/src/InMemoryLiveQueryStore.ts index 19350bd7..332b0155 100644 --- a/packages/in-memory-live-query-store/src/InMemoryLiveQueryStore.ts +++ b/packages/in-memory-live-query-store/src/InMemoryLiveQueryStore.ts @@ -77,8 +77,8 @@ export class InMemoryLiveQueryStore implements LiveQueryStore { private _cache = new Map(); private _buildResourceIdentifier = defaultResourceIdentifierNormalizer; - constructor(params: InMemoryLiveQueryStoreParameter) { - if (params.buildResourceIdentifier) { + constructor(params?: InMemoryLiveQueryStoreParameter) { + if (params?.buildResourceIdentifier) { this._buildResourceIdentifier = params.buildResourceIdentifier; } } @@ -153,11 +153,18 @@ export class InMemoryLiveQueryStore implements LiveQueryStore { return () => void this._store.delete(operationDocument); } - async triggerUpdate(identifier: string) { - for (const record of this._store.values()) { - if (record.identifier.has(identifier)) { - const result = await record.executeOperation(); - record.publishUpdate(result, result); + async emit(identifiers: string[] | string) { + if (typeof identifiers === "string") { + identifiers = [identifiers]; + } + + // Todo it might be better to simply use a hash map of the events ninstead of iterating through everything... + for (const identifier of identifiers) { + for (const record of this._store.values()) { + if (record.identifier.has(identifier)) { + const result = await record.executeOperation(); + record.publishUpdate(result, result); + } } } } diff --git a/packages/todo-example/server/src/main.ts b/packages/todo-example/server/src/main.ts index c815408b..c55c3d7b 100644 --- a/packages/todo-example/server/src/main.ts +++ b/packages/todo-example/server/src/main.ts @@ -22,7 +22,7 @@ const server = app .listen(parsePortSafe(process.env.PORT || "3001")); const socketServer = socketIO(server); -const liveQueryStore = new InMemoryLiveQueryStore({}); +const liveQueryStore = new InMemoryLiveQueryStore(); const rootValue = { todos: new Map(), diff --git a/packages/todo-example/server/src/schema.ts b/packages/todo-example/server/src/schema.ts index 3493350b..ee4b091e 100644 --- a/packages/todo-example/server/src/schema.ts +++ b/packages/todo-example/server/src/schema.ts @@ -116,7 +116,7 @@ const GraphQLMutationType = new GraphQLObjectType({ isCompleted: false, }; root.todos.set(args.id, addedTodo); - context.liveQueryStore.triggerUpdate(`Query.todos`); + context.liveQueryStore.emit(`Query.todos`); return { addedTodo, }; @@ -131,7 +131,7 @@ const GraphQLMutationType = new GraphQLObjectType({ }, resolve: (root, args, context) => { root.todos.delete(args.id); - context.liveQueryStore.triggerUpdate(`Query.todos`); + context.liveQueryStore.emit(`Query.todos`); return { removedTodoId: args.id, }; @@ -150,7 +150,7 @@ const GraphQLMutationType = new GraphQLObjectType({ throw new Error(`Todo with id '${args.id}' does not exist.`); } todo.isCompleted = !todo.isCompleted; - context.liveQueryStore.triggerUpdate(`Todo:${args.id}`); + context.liveQueryStore.emit(`Todo:${args.id}`); return { toggledTodo: todo, }; @@ -172,7 +172,7 @@ const GraphQLMutationType = new GraphQLObjectType({ throw new Error(`Todo with id '${args.id}' does not exist.`); } todo.content = args.content; - context.liveQueryStore.triggerUpdate(`Todo:${args.id}`); + context.liveQueryStore.emit(`Todo:${args.id}`); return { changedTodo: todo, };