@messenger-box/platform-client 10.0.3-alpha.34 → 10.0.3-alpha.37

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.37](https://github.com/CDEBase/messenger-box/compare/v10.0.3-alpha.36...v10.0.3-alpha.37) (2025-04-25)
7
+
8
+ **Note:** Version bump only for package @messenger-box/platform-client
9
+
10
+ ## [10.0.3-alpha.36](https://github.com/CDEBase/messenger-box/compare/v10.0.3-alpha.35...v10.0.3-alpha.36) (2025-04-23)
11
+
12
+ **Note:** Version bump only for package @messenger-box/platform-client
13
+
6
14
  ## [10.0.3-alpha.34](https://github.com/CDEBase/messenger-box/compare/v10.0.3-alpha.33...v10.0.3-alpha.34) (2025-04-22)
7
15
 
8
16
  **Note:** Version bump only for package @messenger-box/platform-client
@@ -16,9 +16,9 @@ fragment Post on Post {
16
16
  fromServer
17
17
  updatedAt
18
18
 
19
- # propsConfiguration {
20
- # ...Configuration
21
- # }
19
+ propsConfiguration {
20
+ ...Configuration
21
+ }
22
22
  props
23
23
  files {
24
24
  totalCount
@@ -55,9 +55,9 @@ fragment PostReplies on Messages {
55
55
  createdAt
56
56
  fromServer
57
57
  updatedAt
58
- # propsConfiguration {
59
- # ...Configuration
60
- # }
58
+ propsConfiguration {
59
+ ...Configuration
60
+ }
61
61
  props
62
62
  files {
63
63
  totalCount
@@ -95,9 +95,9 @@ fragment PostWithoutReplies on Post {
95
95
  fromServer
96
96
  updatedAt
97
97
 
98
- # propsConfiguration {
99
- # ...Configuration
100
- # }
98
+ propsConfiguration {
99
+ ...Configuration
100
+ }
101
101
  props
102
102
  files {
103
103
  totalCount
@@ -1 +1 @@
1
- {"version":3,"file":"messages-policies.d.ts","sourceRoot":"","sources":["../../../src/graphql/policies/messages-policies.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,eAAO,MAAM,gBAAgB,EAAE,YA0G9B,CAAC"}
1
+ {"version":3,"file":"messages-policies.d.ts","sourceRoot":"","sources":["../../../src/graphql/policies/messages-policies.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,eAAO,MAAM,gBAAgB,EAAE,YA2L9B,CAAC"}
@@ -27,29 +27,40 @@ const messagesPolicies = {
27
27
  }
28
28
  },
29
29
  data: {
30
- keyArgs: false,
30
+ keyArgs: ['channelId', 'parentId'],
31
31
  merge: (existing = [], incoming = [], {
32
32
  readField,
33
33
  mergeObjects
34
34
  }) => {
35
- // console.log('existing', existing);
36
- // console.log('incoming', incoming);
37
- const merged = [...incoming];
38
- const existingIds = existing.map(item => readField('id', item));
39
- merged.forEach((item, index) => {
40
- const itemId = readField('id', item);
41
- const existingIndex = existingIds.findIndex(id => id === itemId);
42
- if (existingIndex !== -1) {
43
- merged[index] = mergeObjects(existing[existingIndex], merged[index]);
35
+ // Create a map of existing messages by ID for efficient lookups
36
+ const existingMap = new Map();
37
+ existing.forEach(item => {
38
+ const id = readField('id', item);
39
+ if (id) existingMap.set(id, item);
40
+ });
41
+ // Create a new array by merging incoming with existing
42
+ const merged = incoming.map(incomingItem => {
43
+ const id = readField('id', incomingItem);
44
+ // If item already exists, merge them, otherwise use incoming
45
+ if (id && existingMap.has(id)) {
46
+ return mergeObjects(existingMap.get(id), incomingItem);
47
+ }
48
+ return incomingItem;
49
+ });
50
+ // Add any existing items that aren't in the incoming list
51
+ existing.forEach(existingItem => {
52
+ const id = readField('id', existingItem);
53
+ if (id && !merged.some(item => readField('id', item) === id)) {
54
+ merged.push(existingItem);
44
55
  }
45
56
  });
46
57
  return merged;
47
58
  }
48
59
  },
49
60
  totalCount: {
50
- keyArgs: false,
61
+ keyArgs: ['channelId', 'parentId'],
51
62
  merge(existing, incoming) {
52
- return existing && existing > incoming ? existing : incoming;
63
+ return incoming !== undefined ? incoming : existing;
53
64
  }
54
65
  }
55
66
  // data: {
@@ -96,32 +107,89 @@ const messagesPolicies = {
96
107
  Query: {
97
108
  fields: {
98
109
  messages: {
99
- // keyArgs: ['channelId', 'parentId', 'limit', 'skip'],
100
- // keyArgs: ['channelId', 'parentId'],
110
+ keyArgs: ['channelId', 'parentId'],
111
+ merge(existing, incoming, {
112
+ args,
113
+ readField
114
+ }) {
115
+ if (!incoming) return existing;
116
+ if (!existing) return incoming;
117
+ // Create a deep copy of the existing data
118
+ const result = {
119
+ ...existing,
120
+ totalCount: incoming.totalCount ?? existing.totalCount
121
+ };
122
+ // If there's no data in either, return the basic structure
123
+ if (!existing.data || !incoming.data) {
124
+ return result;
125
+ }
126
+ // Create a map of existing messages by ID
127
+ const existingMessages = new Map();
128
+ existing.data.forEach(message => {
129
+ const id = readField('id', message);
130
+ if (id) existingMessages.set(id, message);
131
+ });
132
+ // Create merged data array with deduplication
133
+ let mergedData = [...existing.data];
134
+ // Add new messages, replacing existing ones with same ID
135
+ incoming.data.forEach(incomingMessage => {
136
+ const id = readField('id', incomingMessage);
137
+ if (!id) return;
138
+ // If message already exists, update it at its current position
139
+ const existingIndex = mergedData.findIndex(msg => readField('id', msg) === id);
140
+ if (existingIndex >= 0) {
141
+ // Replace the existing message with the incoming one
142
+ mergedData[existingIndex] = incomingMessage;
143
+ } else {
144
+ // Add the new message
145
+ // For optimistic updates with sendMessage mutation, we want to add to the beginning
146
+ // For pagination/fetchMore, we should add according to the sort order
147
+ if (args && args.skip === 0) {
148
+ // This is likely a new message or an optimistic update
149
+ mergedData.unshift(incomingMessage);
150
+ } else {
151
+ // This is likely from pagination
152
+ mergedData.push(incomingMessage);
153
+ }
154
+ }
155
+ });
156
+ // Ensure no duplicate messages
157
+ const uniqueIds = new Set();
158
+ mergedData = mergedData.filter(message => {
159
+ const id = readField('id', message);
160
+ if (!id || uniqueIds.has(id)) return false;
161
+ uniqueIds.add(id);
162
+ return true;
163
+ });
164
+ return {
165
+ ...result,
166
+ data: mergedData
167
+ };
168
+ }
169
+ }
170
+ }
171
+ },
172
+ Post: {
173
+ fields: {
174
+ replies: {
175
+ merge(existing, incoming) {
176
+ if (!incoming) return existing;
177
+ if (!existing) return incoming;
178
+ return {
179
+ ...incoming,
180
+ data: [...(existing?.data || []), ...(incoming?.data || [])].filter((message, index, self) => index === self.findIndex(m => m.id === message.id))
181
+ };
182
+ }
183
+ },
184
+ files: {
101
185
  merge(existing, incoming) {
186
+ if (!incoming) return existing;
187
+ if (!existing) return incoming;
102
188
  return {
103
189
  ...incoming,
104
- data: [...(existing?.data ?? []), ...(incoming.data ?? [])]
190
+ data: [...(existing?.data || []), ...(incoming?.data || [])].filter((file, index, self) => index === self.findIndex(f => f.id === file.id))
105
191
  };
106
192
  }
107
- // merge(existing, incoming, { args, mergeObjects }) {
108
- // console.log('existing length', existing?.data?.length);
109
- // console.log('incoming length', incoming?.data?.length);
110
- // // console.log('existing', JSON.stringify(existing), 'incoming', JSON.stringify(incoming));
111
- // if (!incoming || incoming?.data?.length) return existing;
112
- // if (!existing || existing?.data?.length) return incoming;
113
- // //console.log('existing', JSON.stringify(existing), 'incoming', JSON.stringify(incoming));
114
- // const mergedData = existing ? existing?.data?.slice(0) : [];
115
- // // Insert the incoming elements in the right places, according to args.
116
- // const end = args?.skip + Math.min(args?.limit, incoming?.data?.length);
117
- // for (let i = args?.skip; i < end; ++i) {
118
- // mergedData[i] = incoming?.data[i - args?.skip];
119
- // }
120
- // const merged = { ...incoming, data: mergedData };
121
- // return merged;
122
- // // return mergeObjects(existing, incoming);
123
- // //return existing ? { ...existing, ...incoming } : incoming;
124
- // },
125
193
  }
126
194
  }
127
195
  }
@@ -1 +1 @@
1
- {"version":3,"file":"messages-policies.js","sources":["../../../src/graphql/policies/messages-policies.ts"],"sourcesContent":[null],"names":[],"mappings":"AAEa,MAAA,gBAAgB,GAAiB;AAC1C,EAAA,QAAA,EAAQ;;;;AAIJ,IAAA,MAAA,EAAA;AACI,MAAA,EAAA,EAAA;AACI,QAAA,IAAA,CAAA,QAAK,EAAA;AACD,UAAA;AACA,SAAA,EAAA;gBACJ;AACH,YAAA,SAAA;AACD,YAAA;AACI,WAAA,GAAA,SAAK;AACD,UAAA,OAAA,QAAA,GAAQ,CAAS,EAAA,qBAAoB,iBAAU,CAAA,CAAA;AAC/C;;AAEP,MAAA,aAAA,EAAA;AACD,QAAA,IAAA,CAAA,QAAM,EAAA;AACF,UAAA;AACA,SAAA,EAAA;;qBAEyC;AACrC,YAAA;AACA,WAAA,GAAA,SAAA;yBAEM,eAAc,CAAE,CAAA,EAAA,QAAS,CAAA,CAAA,GAAA,CAAA,EAAA,SAAA,CAAA,CAAA;;AAE3B,OAAA;AACA,MAAA,IAAA,EAAA;AACI,QAAA,OAAA,EAAA,KAAA;wBACJ,GAAC,EAAA,EAAA,QAAA,GAAA,EAAA,EAAA;AACL,UAAA,SAAA;AACA,UAAA;;AAEP;AACD;AACI,UAAA,MAAA,MAAA,GAAS,CAAK,GAAA,QAAA,CAAA;gBACd,WAAc,GAAA,QAAU,CAAA,GAAA,CAAA,IAAA,IAAA,SAAA,CAAA,IAAA,EAAA,IAAA,CAAA,CAAA;AACpB,UAAA,MAAA,CAAA,OAAA,CAAA,CAAA,IAAe,EAAA,KAAA,KAAY;kBAC9B,MAAA,GAAA,SAAA,CAAA,IAAA,EAAA,IAAA,CAAA;AACJ,YAAA,MAAA,aAAA,GAAA,WAAA,CAAA,SAAA,CAAA,EAAA,IAAA,EAAA,KAAA,MAAA,CAAA;YACD,IAAU,aAAA,KAAA,EAAA,EAAA;cACgD,MAAA,CAAA,KAAA,CAAA,GAAA,YAAA,CAAA,QAAA,CAAA,aAAA,CAAA,EAAA,MAAA,CAAA,KAAA,CAAA,CAAA;;YAE1D;iBACkF,MAAA;;;gBAG9B,EAAA;eACxC,EAAA,KAAA;aACa,CAAA,QAAA,EAAA,QAAA,EAAA;iBAChB,QAAA,IAAA,QAAA,GAAA,QAAA,GAAA,QAAA,GAAA,QAAA;;AAEZ;AACJ;AACD;;AAEI;AACI;AACI;AACI;AACA;;AAEP;AACD;AACI;AACI;AACA,GAAA;oBACH,EAAA;AACJ;AACJ,IAAA,MAAA,EAAA;AACJ,MAAA,mBAAA,EAAA;AACD,QAAA,IAAO,CAAA,QAAA,EAAA;AACH,UAAA;AACI,SAAA,EAAA;gBACI;qBACsC;;uBAE3B;AACH,UAAA,OAAA,QAAA,GAAW,CAAA,EAAA,SAAA,CAAA,CAAA,EAAA,QAAA,CAAA,CAAA,GAAA,CAAA,EAAA,SAAA,CAAA,CAAA;AACX;;;qBAG8C,EAAA;;;gBAGtD;qBACgE;;uBAEiC;iBAC9B,QAAA,GAAA,CAAA,EAAA,SAAA,CAAA,CAAA,EAAA,QAAA,CAAA,CAAA,GAAA,CAAA,EAAA,SAAA,CAAA,CAAA;;;;;;;gBAQnE;;;sBAGK,EAAA,QAAA,EAAA;AACR,UAAA,OAAA;AACJ,YAAA,GAAA,QAAA;AACJ,YAAA,IAAA,EAAA,CAAA,IAAA,QAAA,EAAA,IAAA,IAAA,EAAA,CAAA,EAAA,IAAA,QAAA,CAAA,IAAA,IAAA,EAAA,CAAA;WACH;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"messages-policies.js","sources":["../../../src/graphql/policies/messages-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.34",
3
+ "version": "10.0.3-alpha.37",
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.6",
24
- "@messenger-box/core": "10.0.3-alpha.34",
24
+ "@messenger-box/core": "10.0.3-alpha.36",
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": "33c7bdb4f36c40b6368a5c96fe6312de009188a1"
38
+ "gitHead": "4a360a1be756050ed8c3c1cd61a037c6109f8866"
39
39
  }
@@ -16,9 +16,9 @@ fragment Post on Post {
16
16
  fromServer
17
17
  updatedAt
18
18
 
19
- # propsConfiguration {
20
- # ...Configuration
21
- # }
19
+ propsConfiguration {
20
+ ...Configuration
21
+ }
22
22
  props
23
23
  files {
24
24
  totalCount
@@ -55,9 +55,9 @@ fragment PostReplies on Messages {
55
55
  createdAt
56
56
  fromServer
57
57
  updatedAt
58
- # propsConfiguration {
59
- # ...Configuration
60
- # }
58
+ propsConfiguration {
59
+ ...Configuration
60
+ }
61
61
  props
62
62
  files {
63
63
  totalCount
@@ -95,9 +95,9 @@ fragment PostWithoutReplies on Post {
95
95
  fromServer
96
96
  updatedAt
97
97
 
98
- # propsConfiguration {
99
- # ...Configuration
100
- # }
98
+ propsConfiguration {
99
+ ...Configuration
100
+ }
101
101
  props
102
102
  files {
103
103
  totalCount
@@ -19,27 +19,40 @@ export const messagesPolicies: TypePolicies = {
19
19
  },
20
20
  },
21
21
  data: {
22
- keyArgs: false,
22
+ keyArgs: ['channelId', 'parentId'],
23
23
  merge: (existing = [], incoming = [], { readField, mergeObjects }) => {
24
- // console.log('existing', existing);
25
- // console.log('incoming', incoming);
26
- const merged = [...incoming];
27
- const existingIds = existing.map((item) => readField<String>('id', item));
24
+ // Create a map of existing messages by ID for efficient lookups
25
+ const existingMap = new Map();
26
+ existing.forEach((item) => {
27
+ const id = readField<string>('id', item);
28
+ if (id) existingMap.set(id, item);
29
+ });
28
30
 
29
- merged.forEach((item, index) => {
30
- const itemId = readField<String>('id', item);
31
- const existingIndex = existingIds.findIndex((id) => id === itemId);
32
- if (existingIndex !== -1) {
33
- merged[index] = mergeObjects(existing[existingIndex], merged[index]);
31
+ // Create a new array by merging incoming with existing
32
+ const merged = incoming.map((incomingItem) => {
33
+ const id = readField<string>('id', incomingItem);
34
+ // If item already exists, merge them, otherwise use incoming
35
+ if (id && existingMap.has(id)) {
36
+ return mergeObjects(existingMap.get(id), incomingItem);
34
37
  }
38
+ return incomingItem;
35
39
  });
40
+
41
+ // Add any existing items that aren't in the incoming list
42
+ existing.forEach((existingItem) => {
43
+ const id = readField<string>('id', existingItem);
44
+ if (id && !merged.some((item) => readField<string>('id', item) === id)) {
45
+ merged.push(existingItem);
46
+ }
47
+ });
48
+
36
49
  return merged;
37
50
  },
38
51
  },
39
52
  totalCount: {
40
- keyArgs: false,
53
+ keyArgs: ['channelId', 'parentId'],
41
54
  merge(existing, incoming) {
42
- return existing && existing > incoming ? existing : incoming;
55
+ return incoming !== undefined ? incoming : existing;
43
56
  },
44
57
  },
45
58
  // data: {
@@ -57,7 +70,7 @@ export const messagesPolicies: TypePolicies = {
57
70
  },
58
71
  },
59
72
  PostThreadMessages: {
60
- // keyFields: ['threadmessagesRefId'],
73
+ // keyFields: ['threadmessagesRefId'],
61
74
  fields: {
62
75
  threadmessagesRefId: {
63
76
  read(existing, { variables }) {
@@ -76,33 +89,101 @@ export const messagesPolicies: TypePolicies = {
76
89
  Query: {
77
90
  fields: {
78
91
  messages: {
79
- // keyArgs: ['channelId', 'parentId', 'limit', 'skip'],
80
- // keyArgs: ['channelId', 'parentId'],
92
+ keyArgs: ['channelId', 'parentId'],
93
+ merge(existing, incoming, { args, readField }) {
94
+ if (!incoming) return existing;
95
+ if (!existing) return incoming;
96
+
97
+ // Create a deep copy of the existing data
98
+ const result = {
99
+ ...existing,
100
+ totalCount: incoming.totalCount ?? existing.totalCount,
101
+ };
102
+
103
+ // If there's no data in either, return the basic structure
104
+ if (!existing.data || !incoming.data) {
105
+ return result;
106
+ }
107
+
108
+ // Create a map of existing messages by ID
109
+ const existingMessages = new Map();
110
+ existing.data.forEach((message) => {
111
+ const id = readField<string>('id', message);
112
+ if (id) existingMessages.set(id, message);
113
+ });
114
+
115
+ // Create merged data array with deduplication
116
+ let mergedData = [...existing.data];
117
+
118
+ // Add new messages, replacing existing ones with same ID
119
+ incoming.data.forEach((incomingMessage) => {
120
+ const id = readField<string>('id', incomingMessage);
121
+ if (!id) return;
122
+
123
+ // If message already exists, update it at its current position
124
+ const existingIndex = mergedData.findIndex((msg) => readField<string>('id', msg) === id);
125
+
126
+ if (existingIndex >= 0) {
127
+ // Replace the existing message with the incoming one
128
+ mergedData[existingIndex] = incomingMessage;
129
+ } else {
130
+ // Add the new message
131
+ // For optimistic updates with sendMessage mutation, we want to add to the beginning
132
+ // For pagination/fetchMore, we should add according to the sort order
133
+ if (args && args.skip === 0) {
134
+ // This is likely a new message or an optimistic update
135
+ mergedData.unshift(incomingMessage);
136
+ } else {
137
+ // This is likely from pagination
138
+ mergedData.push(incomingMessage);
139
+ }
140
+ }
141
+ });
142
+
143
+ // Ensure no duplicate messages
144
+ const uniqueIds = new Set();
145
+ mergedData = mergedData.filter((message) => {
146
+ const id = readField<string>('id', message);
147
+ if (!id || uniqueIds.has(id)) return false;
148
+ uniqueIds.add(id);
149
+ return true;
150
+ });
151
+
152
+ return {
153
+ ...result,
154
+ data: mergedData,
155
+ };
156
+ },
157
+ },
158
+ },
159
+ },
160
+ Post: {
161
+ fields: {
162
+ replies: {
81
163
  merge(existing, incoming) {
164
+ if (!incoming) return existing;
165
+ if (!existing) return incoming;
166
+
82
167
  return {
83
168
  ...incoming,
84
- data: [...(existing?.data ?? []), ...(incoming.data ?? [])],
169
+ data: [...(existing?.data || []), ...(incoming?.data || [])].filter(
170
+ (message, index, self) => index === self.findIndex((m) => m.id === message.id),
171
+ ),
85
172
  };
86
173
  },
87
- // merge(existing, incoming, { args, mergeObjects }) {
88
- // console.log('existing length', existing?.data?.length);
89
- // console.log('incoming length', incoming?.data?.length);
90
- // // console.log('existing', JSON.stringify(existing), 'incoming', JSON.stringify(incoming));
91
- // if (!incoming || incoming?.data?.length) return existing;
92
- // if (!existing || existing?.data?.length) return incoming;
93
- // //console.log('existing', JSON.stringify(existing), 'incoming', JSON.stringify(incoming));
94
- // const mergedData = existing ? existing?.data?.slice(0) : [];
95
- // // Insert the incoming elements in the right places, according to args.
96
- // const end = args?.skip + Math.min(args?.limit, incoming?.data?.length);
97
- // for (let i = args?.skip; i < end; ++i) {
98
- // mergedData[i] = incoming?.data[i - args?.skip];
99
- // }
174
+ },
175
+ files: {
176
+ merge(existing, incoming) {
177
+ if (!incoming) return existing;
178
+ if (!existing) return incoming;
100
179
 
101
- // const merged = { ...incoming, data: mergedData };
102
- // return merged;
103
- // // return mergeObjects(existing, incoming);
104
- // //return existing ? { ...existing, ...incoming } : incoming;
105
- // },
180
+ return {
181
+ ...incoming,
182
+ data: [...(existing?.data || []), ...(incoming?.data || [])].filter(
183
+ (file, index, self) => index === self.findIndex((f) => f.id === file.id),
184
+ ),
185
+ };
186
+ },
106
187
  },
107
188
  },
108
189
  },