@messenger-box/platform-client 10.0.3-alpha.62 → 10.0.3-alpha.69

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/CHANGELOG.md CHANGED
@@ -3,6 +3,14 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [10.0.3-alpha.69](https://github.com/CDEBase/messenger-box/compare/v10.0.3-alpha.68...v10.0.3-alpha.69) (2025-08-11)
7
+
8
+ **Note:** Version bump only for package @messenger-box/platform-client
9
+
10
+ ## [10.0.3-alpha.67](https://github.com/CDEBase/messenger-box/compare/v10.0.3-alpha.66...v10.0.3-alpha.67) (2025-08-06)
11
+
12
+ **Note:** Version bump only for package @messenger-box/platform-client
13
+
6
14
  ## [10.0.3-alpha.62](https://github.com/CDEBase/messenger-box/compare/v10.0.3-alpha.61...v10.0.3-alpha.62) (2025-07-30)
7
15
 
8
16
  **Note:** Version bump only for package @messenger-box/platform-client
@@ -1 +1 @@
1
- {"version":3,"file":"channel-policies.d.ts","sourceRoot":"","sources":["../../../src/graphql/policies/channel-policies.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,eAAO,MAAM,eAAe,EAAE,YA8D7B,CAAC"}
1
+ {"version":3,"file":"channel-policies.d.ts","sourceRoot":"","sources":["../../../src/graphql/policies/channel-policies.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAO,MAAM,gBAAgB,CAAC;AAEnD,eAAO,MAAM,eAAe,EAAE,YAsJ7B,CAAC"}
@@ -1,13 +1,44 @@
1
- const channelPolicies = {
1
+ import {gql}from'@apollo/client/index.js';const channelPolicies = {
2
2
  Query: {
3
3
  fields: {
4
4
  channelsByUser: {
5
- merge(existing = [], incoming) {
6
- // Use newer data from server to completely replace existing data
7
- return incoming;
5
+ keyArgs: ['role', 'criteria', 'limit', 'skip', 'sort'],
6
+ merge(existing = [], incoming = [], {
7
+ readField
8
+ }) {
9
+ // If no existing data, just return incoming
10
+ if (!existing || existing.length === 0) {
11
+ return incoming;
12
+ }
13
+ // If no incoming data, keep existing
14
+ if (!incoming || incoming.length === 0) {
15
+ return existing;
16
+ }
17
+ // Create a map for efficient lookup
18
+ const channelMap = new Map();
19
+ // Add existing channels to map
20
+ for (let i = 0; i < existing.length; i++) {
21
+ const channel = existing[i];
22
+ if (channel) {
23
+ const id = readField('id', channel);
24
+ if (id) {
25
+ channelMap.set(id, channel);
26
+ }
27
+ }
28
+ }
29
+ // Merge in incoming channels, overwriting existing ones
30
+ for (let i = 0; i < incoming.length; i++) {
31
+ const channel = incoming[i];
32
+ if (channel) {
33
+ const id = readField('id', channel);
34
+ if (id) {
35
+ channelMap.set(id, channel);
36
+ }
37
+ }
38
+ }
39
+ // Convert map values back to array
40
+ return Array.from(channelMap.values());
8
41
  },
9
- // Enable pagination with keyArgs to correctly identify cache entries
10
- keyArgs: ['criteria', 'role', 'limit'],
11
42
  // Add a read function for more control over cache reads
12
43
  read(existing, {
13
44
  args
@@ -48,8 +79,63 @@ const channelPolicies = {
48
79
  }
49
80
  },
50
81
  lastMessage: {
51
- read(lastMessage) {
52
- return lastMessage || null;
82
+ merge(existing, incoming, {
83
+ readField
84
+ }) {
85
+ // If no incoming message, keep existing
86
+ if (!incoming) return existing;
87
+ // If no existing message, use incoming
88
+ if (!existing) return incoming;
89
+ // Compare timestamps to determine which is newer
90
+ const existingCreatedAt = readField('createdAt', existing);
91
+ const incomingCreatedAt = readField('createdAt', incoming);
92
+ if (existingCreatedAt && incomingCreatedAt) {
93
+ // Use the more recent message
94
+ return new Date(incomingCreatedAt) > new Date(existingCreatedAt) ? incoming : existing;
95
+ }
96
+ // If timestamps are not available, prefer incoming
97
+ return incoming;
98
+ },
99
+ read(lastMessage, {
100
+ readField,
101
+ cache,
102
+ args
103
+ }) {
104
+ // If lastMessage is already available, return it
105
+ if (lastMessage) return lastMessage;
106
+ // Try to get the channel ID to reference messages cache
107
+ const channelId = readField('id');
108
+ if (!channelId) return null;
109
+ try {
110
+ // Read messages from cache for this channel
111
+ const messagesQuery = cache.readQuery({
112
+ query: gql`
113
+ query GetChannelMessages($channelId: String!) {
114
+ messages(channelId: $channelId, skip: 0, limit: 1) {
115
+ data {
116
+ id
117
+ content
118
+ createdAt
119
+ updatedAt
120
+ user {
121
+ id
122
+ username
123
+ displayName
124
+ }
125
+ }
126
+ }
127
+ }
128
+ `,
129
+ variables: {
130
+ channelId
131
+ }
132
+ });
133
+ // Return the first (latest) message if available
134
+ return messagesQuery?.messages?.data?.[0] || null;
135
+ } catch (error) {
136
+ // If messages query fails, return null
137
+ return null;
138
+ }
53
139
  }
54
140
  }
55
141
  }
@@ -1 +1 @@
1
- {"version":3,"file":"channel-policies.js","sources":["../../../src/graphql/policies/channel-policies.ts"],"sourcesContent":[null],"names":[],"mappings":"AAEa,MAAA,eAAe,GAAiB;AACzC,EAAA,KAAA,EAAK;AACD,IAAA,MAAA,EAAA;AACI,MAAA,cAAA,EAAA;AACI,QAAA,KAAA,CAAA,QAAM,GAAA,EAAA,EAAA,QAAe,EAAQ;;AAEzB,UAAA,OAAA,QAAA;;;AAGJ,QAAA,OAAA,EAAA,CAAA,UAAU,EAAA,MAAU,EAAE,OAAM,CAAE;;AAE9B,QAAA,IAAA,CAAA,QAAK,EAAA;;AAED,SAAA,EAAA;AAAe;AACf,UAAA,IAAA,CAAA,QAAA,EAAA,gBAAgB;iBACnB,QAAA;AACJ;AACJ;AACJ;AACD,GAAA;SACa,EAAA;AACT,IAAA,SAAA,EAAQ,CAAA,IAAA,CAAA;AACJ,IAAA,MAAA,EAAA;AACI,MAAA,OAAA,EAAA;AACI,QAAA,KAAA,CAAA,QAAA,GAAA,EAAO,UAAS,EAAA;iBACnB,QAAA;AACJ;;AAED;AACI,MAAA,KAAA,EAAA;oBACI;iBACH,KAAA,IAAA,EAAA;AACJ;AACD,OAAA;AACI,MAAA,WAAA,EAAA;wBACW,EAAA;iBACV,WAAA,IAAA,EAAA;AACJ;;AAED;AACI,MAAA,WAAA,EAAA;AACI,QAAA,IAAA,CAAA,CAAA,EAAA;AACA,UAAA;;AAEP,UAAA,MAAA,OAAA,GAAA,SAAA,CAAA,SAAA,CAAA;AACD,UAAA,OAAA,OAAa,IAAA,KAAA,CAAA,OAAA,CAAA,OAAA,CAAA,GAAA,OAAA,CAAA,MAAA,GAAA,CAAA;AACT;;iBAEC,EAAA;AACJ,QAAA,IAAA,CAAA,WAAA,EAAA;AACJ,UAAA,OAAA,WAAA,IAAA,IAAA;AACJ;;AAED;;AAEI;AACI,EAAA,aAAA,EAAM;gBACF,IAA6C,CAAA;AAC7C,IAAA,MAAA,EAAA;AACH,MAAA,IAAA,EAAA;AACJ;AACJ,QAAA,KAAA,EAAA;;;;"}
1
+ {"version":3,"file":"channel-policies.js","sources":["../../../src/graphql/policies/channel-policies.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@messenger-box/platform-client",
3
- "version": "10.0.3-alpha.62",
3
+ "version": "10.0.3-alpha.69",
4
4
  "description": "Sample core for higher packages to depend on",
5
5
  "license": "ISC",
6
6
  "author": "CDMBase LLC",
@@ -21,7 +21,7 @@
21
21
  },
22
22
  "dependencies": {
23
23
  "@container-stack/file-info-client": "^5.4.1-alpha.9",
24
- "@messenger-box/core": "10.0.3-alpha.62",
24
+ "@messenger-box/core": "10.0.3-alpha.69",
25
25
  "key-mirror": "1.0.1",
26
26
  "moment-timezone": "0.5.33"
27
27
  },
@@ -35,5 +35,5 @@
35
35
  "typescript": {
36
36
  "definition": "lib/index.d.ts"
37
37
  },
38
- "gitHead": "8b546a2c05aecf314c1c8e94245810a945e90899"
38
+ "gitHead": "011fbbc8fbbc97043d73323c02c1ac22b2a01bfb"
39
39
  }
@@ -1,15 +1,49 @@
1
- import { TypePolicies } from '@apollo/client';
1
+ import { TypePolicies, gql } from '@apollo/client';
2
2
 
3
3
  export const channelPolicies: TypePolicies = {
4
4
  Query: {
5
5
  fields: {
6
6
  channelsByUser: {
7
- merge(existing = [], incoming) {
8
- // Use newer data from server to completely replace existing data
9
- return incoming;
7
+ keyArgs: ['role', 'criteria', 'limit', 'skip', 'sort'],
8
+ merge(existing = [], incoming = [], { readField }) {
9
+ // If no existing data, just return incoming
10
+ if (!existing || existing.length === 0) {
11
+ return incoming;
12
+ }
13
+
14
+ // If no incoming data, keep existing
15
+ if (!incoming || incoming.length === 0) {
16
+ return existing;
17
+ }
18
+
19
+ // Create a map for efficient lookup
20
+ const channelMap = new Map();
21
+
22
+ // Add existing channels to map
23
+ for (let i = 0; i < existing.length; i++) {
24
+ const channel = existing[i];
25
+ if (channel) {
26
+ const id = readField('id', channel);
27
+ if (id) {
28
+ channelMap.set(id, channel);
29
+ }
30
+ }
31
+ }
32
+
33
+ // Merge in incoming channels, overwriting existing ones
34
+ for (let i = 0; i < incoming.length; i++) {
35
+ const channel = incoming[i];
36
+ if (channel) {
37
+ const id = readField('id', channel);
38
+ if (id) {
39
+ channelMap.set(id, channel);
40
+ }
41
+ }
42
+ }
43
+
44
+ // Convert map values back to array
45
+ return Array.from(channelMap.values());
10
46
  },
11
- // Enable pagination with keyArgs to correctly identify cache entries
12
- keyArgs: ['criteria', 'role', 'limit'],
13
47
  // Add a read function for more control over cache reads
14
48
  read(existing, { args }) {
15
49
  // Return undefined to force a network request if data doesn't exist
@@ -46,8 +80,62 @@ export const channelPolicies: TypePolicies = {
46
80
  },
47
81
  },
48
82
  lastMessage: {
49
- read(lastMessage) {
50
- return lastMessage || null;
83
+ merge(existing, incoming, { readField }) {
84
+ // If no incoming message, keep existing
85
+ if (!incoming) return existing;
86
+
87
+ // If no existing message, use incoming
88
+ if (!existing) return incoming;
89
+
90
+ // Compare timestamps to determine which is newer
91
+ const existingCreatedAt = readField('createdAt', existing) as string | number | Date;
92
+ const incomingCreatedAt = readField('createdAt', incoming) as string | number | Date;
93
+
94
+ if (existingCreatedAt && incomingCreatedAt) {
95
+ // Use the more recent message
96
+ return new Date(incomingCreatedAt) > new Date(existingCreatedAt) ? incoming : existing;
97
+ }
98
+
99
+ // If timestamps are not available, prefer incoming
100
+ return incoming;
101
+ },
102
+ read(lastMessage, { readField, cache, args }) {
103
+ // If lastMessage is already available, return it
104
+ if (lastMessage) return lastMessage;
105
+
106
+ // Try to get the channel ID to reference messages cache
107
+ const channelId = readField('id');
108
+ if (!channelId) return null;
109
+
110
+ try {
111
+ // Read messages from cache for this channel
112
+ const messagesQuery = cache.readQuery({
113
+ query: gql`
114
+ query GetChannelMessages($channelId: String!) {
115
+ messages(channelId: $channelId, skip: 0, limit: 1) {
116
+ data {
117
+ id
118
+ content
119
+ createdAt
120
+ updatedAt
121
+ user {
122
+ id
123
+ username
124
+ displayName
125
+ }
126
+ }
127
+ }
128
+ }
129
+ `,
130
+ variables: { channelId },
131
+ }) as any;
132
+
133
+ // Return the first (latest) message if available
134
+ return messagesQuery?.messages?.data?.[0] || null;
135
+ } catch (error) {
136
+ // If messages query fails, return null
137
+ return null;
138
+ }
51
139
  },
52
140
  },
53
141
  },