@claw-network/protocol 0.1.0

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.
Files changed (169) hide show
  1. package/dist/contracts/events.d.ts +238 -0
  2. package/dist/contracts/events.d.ts.map +1 -0
  3. package/dist/contracts/events.js +499 -0
  4. package/dist/contracts/events.js.map +1 -0
  5. package/dist/contracts/index.d.ts +5 -0
  6. package/dist/contracts/index.d.ts.map +1 -0
  7. package/dist/contracts/index.js +5 -0
  8. package/dist/contracts/index.js.map +1 -0
  9. package/dist/contracts/state.d.ts +16 -0
  10. package/dist/contracts/state.d.ts.map +1 -0
  11. package/dist/contracts/state.js +399 -0
  12. package/dist/contracts/state.js.map +1 -0
  13. package/dist/contracts/store.d.ts +19 -0
  14. package/dist/contracts/store.d.ts.map +1 -0
  15. package/dist/contracts/store.js +22 -0
  16. package/dist/contracts/store.js.map +1 -0
  17. package/dist/contracts/types.d.ts +81 -0
  18. package/dist/contracts/types.d.ts.map +1 -0
  19. package/dist/contracts/types.js +2 -0
  20. package/dist/contracts/types.js.map +1 -0
  21. package/dist/dao/events.d.ts +191 -0
  22. package/dist/dao/events.d.ts.map +1 -0
  23. package/dist/dao/events.js +294 -0
  24. package/dist/dao/events.js.map +1 -0
  25. package/dist/dao/index.d.ts +6 -0
  26. package/dist/dao/index.d.ts.map +1 -0
  27. package/dist/dao/index.js +6 -0
  28. package/dist/dao/index.js.map +1 -0
  29. package/dist/dao/state.d.ts +44 -0
  30. package/dist/dao/state.d.ts.map +1 -0
  31. package/dist/dao/state.js +373 -0
  32. package/dist/dao/state.js.map +1 -0
  33. package/dist/dao/store.d.ts +47 -0
  34. package/dist/dao/store.d.ts.map +1 -0
  35. package/dist/dao/store.js +52 -0
  36. package/dist/dao/store.js.map +1 -0
  37. package/dist/dao/types.d.ts +149 -0
  38. package/dist/dao/types.d.ts.map +1 -0
  39. package/dist/dao/types.js +95 -0
  40. package/dist/dao/types.js.map +1 -0
  41. package/dist/dao/voting.d.ts +56 -0
  42. package/dist/dao/voting.d.ts.map +1 -0
  43. package/dist/dao/voting.js +129 -0
  44. package/dist/dao/voting.js.map +1 -0
  45. package/dist/identity/document.d.ts +35 -0
  46. package/dist/identity/document.d.ts.map +1 -0
  47. package/dist/identity/document.js +84 -0
  48. package/dist/identity/document.js.map +1 -0
  49. package/dist/identity/events.d.ts +96 -0
  50. package/dist/identity/events.d.ts.map +1 -0
  51. package/dist/identity/events.js +165 -0
  52. package/dist/identity/events.js.map +1 -0
  53. package/dist/identity/index.d.ts +4 -0
  54. package/dist/identity/index.d.ts.map +1 -0
  55. package/dist/identity/index.js +4 -0
  56. package/dist/identity/index.js.map +1 -0
  57. package/dist/identity/resolver.d.ts +10 -0
  58. package/dist/identity/resolver.d.ts.map +1 -0
  59. package/dist/identity/resolver.js +10 -0
  60. package/dist/identity/resolver.js.map +1 -0
  61. package/dist/index.d.ts +8 -0
  62. package/dist/index.d.ts.map +1 -0
  63. package/dist/index.js +8 -0
  64. package/dist/index.js.map +1 -0
  65. package/dist/markets/broadcast.d.ts +5 -0
  66. package/dist/markets/broadcast.d.ts.map +1 -0
  67. package/dist/markets/broadcast.js +9 -0
  68. package/dist/markets/broadcast.js.map +1 -0
  69. package/dist/markets/capability.d.ts +129 -0
  70. package/dist/markets/capability.d.ts.map +1 -0
  71. package/dist/markets/capability.js +262 -0
  72. package/dist/markets/capability.js.map +1 -0
  73. package/dist/markets/events.d.ts +448 -0
  74. package/dist/markets/events.d.ts.map +1 -0
  75. package/dist/markets/events.js +1074 -0
  76. package/dist/markets/events.js.map +1 -0
  77. package/dist/markets/index.d.ts +12 -0
  78. package/dist/markets/index.d.ts.map +1 -0
  79. package/dist/markets/index.js +12 -0
  80. package/dist/markets/index.js.map +1 -0
  81. package/dist/markets/info-flow.d.ts +144 -0
  82. package/dist/markets/info-flow.d.ts.map +1 -0
  83. package/dist/markets/info-flow.js +257 -0
  84. package/dist/markets/info-flow.js.map +1 -0
  85. package/dist/markets/info-store.d.ts +80 -0
  86. package/dist/markets/info-store.d.ts.map +1 -0
  87. package/dist/markets/info-store.js +384 -0
  88. package/dist/markets/info-store.js.map +1 -0
  89. package/dist/markets/info.d.ts +118 -0
  90. package/dist/markets/info.d.ts.map +1 -0
  91. package/dist/markets/info.js +123 -0
  92. package/dist/markets/info.js.map +1 -0
  93. package/dist/markets/search.d.ts +70 -0
  94. package/dist/markets/search.d.ts.map +1 -0
  95. package/dist/markets/search.js +659 -0
  96. package/dist/markets/search.js.map +1 -0
  97. package/dist/markets/state.d.ts +30 -0
  98. package/dist/markets/state.d.ts.map +1 -0
  99. package/dist/markets/state.js +610 -0
  100. package/dist/markets/state.js.map +1 -0
  101. package/dist/markets/store.d.ts +43 -0
  102. package/dist/markets/store.d.ts.map +1 -0
  103. package/dist/markets/store.js +460 -0
  104. package/dist/markets/store.js.map +1 -0
  105. package/dist/markets/task.d.ts +96 -0
  106. package/dist/markets/task.d.ts.map +1 -0
  107. package/dist/markets/task.js +286 -0
  108. package/dist/markets/task.js.map +1 -0
  109. package/dist/markets/types.d.ts +340 -0
  110. package/dist/markets/types.d.ts.map +1 -0
  111. package/dist/markets/types.js +88 -0
  112. package/dist/markets/types.js.map +1 -0
  113. package/dist/p2p/codec.d.ts +42 -0
  114. package/dist/p2p/codec.d.ts.map +1 -0
  115. package/dist/p2p/codec.js +187 -0
  116. package/dist/p2p/codec.js.map +1 -0
  117. package/dist/p2p/flatbuffers.d.ts +57 -0
  118. package/dist/p2p/flatbuffers.d.ts.map +1 -0
  119. package/dist/p2p/flatbuffers.js +418 -0
  120. package/dist/p2p/flatbuffers.js.map +1 -0
  121. package/dist/p2p/index.d.ts +3 -0
  122. package/dist/p2p/index.d.ts.map +1 -0
  123. package/dist/p2p/index.js +3 -0
  124. package/dist/p2p/index.js.map +1 -0
  125. package/dist/p2p/types.d.ts +79 -0
  126. package/dist/p2p/types.d.ts.map +1 -0
  127. package/dist/p2p/types.js +15 -0
  128. package/dist/p2p/types.js.map +1 -0
  129. package/dist/reputation/anti-cheat.d.ts +24 -0
  130. package/dist/reputation/anti-cheat.d.ts.map +1 -0
  131. package/dist/reputation/anti-cheat.js +109 -0
  132. package/dist/reputation/anti-cheat.js.map +1 -0
  133. package/dist/reputation/events.d.ts +29 -0
  134. package/dist/reputation/events.d.ts.map +1 -0
  135. package/dist/reputation/events.js +122 -0
  136. package/dist/reputation/events.js.map +1 -0
  137. package/dist/reputation/index.d.ts +6 -0
  138. package/dist/reputation/index.d.ts.map +1 -0
  139. package/dist/reputation/index.js +6 -0
  140. package/dist/reputation/index.js.map +1 -0
  141. package/dist/reputation/scoring.d.ts +40 -0
  142. package/dist/reputation/scoring.d.ts.map +1 -0
  143. package/dist/reputation/scoring.js +114 -0
  144. package/dist/reputation/scoring.js.map +1 -0
  145. package/dist/reputation/state.d.ts +48 -0
  146. package/dist/reputation/state.d.ts.map +1 -0
  147. package/dist/reputation/state.js +135 -0
  148. package/dist/reputation/state.js.map +1 -0
  149. package/dist/reputation/store.d.ts +23 -0
  150. package/dist/reputation/store.d.ts.map +1 -0
  151. package/dist/reputation/store.js +33 -0
  152. package/dist/reputation/store.js.map +1 -0
  153. package/dist/wallet/events.d.ts +121 -0
  154. package/dist/wallet/events.d.ts.map +1 -0
  155. package/dist/wallet/events.js +175 -0
  156. package/dist/wallet/events.js.map +1 -0
  157. package/dist/wallet/finality.d.ts +4 -0
  158. package/dist/wallet/finality.d.ts.map +1 -0
  159. package/dist/wallet/finality.js +32 -0
  160. package/dist/wallet/finality.js.map +1 -0
  161. package/dist/wallet/index.d.ts +4 -0
  162. package/dist/wallet/index.d.ts.map +1 -0
  163. package/dist/wallet/index.js +4 -0
  164. package/dist/wallet/index.js.map +1 -0
  165. package/dist/wallet/state.d.ts +32 -0
  166. package/dist/wallet/state.d.ts.map +1 -0
  167. package/dist/wallet/state.js +170 -0
  168. package/dist/wallet/state.js.map +1 -0
  169. package/package.json +42 -0
@@ -0,0 +1,659 @@
1
+ function normalizeTokenAmount(value) {
2
+ if (typeof value === 'bigint') {
3
+ return value;
4
+ }
5
+ if (typeof value === 'number') {
6
+ if (!Number.isFinite(value) || !Number.isInteger(value)) {
7
+ throw new Error('token amount must be an integer');
8
+ }
9
+ return BigInt(value);
10
+ }
11
+ if (typeof value === 'string') {
12
+ if (value.trim().length === 0) {
13
+ throw new Error('token amount is required');
14
+ }
15
+ return BigInt(value);
16
+ }
17
+ throw new Error('token amount is required');
18
+ }
19
+ function tokenizeText(text) {
20
+ const tokens = text
21
+ .toLowerCase()
22
+ .match(/[\p{L}\p{N}]+/gu);
23
+ if (!tokens) {
24
+ return [];
25
+ }
26
+ return tokens.filter((token) => token.length > 0);
27
+ }
28
+ function addToIndex(index, key, id) {
29
+ const normalized = key.toLowerCase();
30
+ const existing = index.get(normalized);
31
+ if (existing) {
32
+ existing.add(id);
33
+ }
34
+ else {
35
+ index.set(normalized, new Set([id]));
36
+ }
37
+ }
38
+ function removeFromIndex(index, key, id) {
39
+ const normalized = key.toLowerCase();
40
+ const existing = index.get(normalized);
41
+ if (!existing) {
42
+ return;
43
+ }
44
+ existing.delete(id);
45
+ if (existing.size === 0) {
46
+ index.delete(normalized);
47
+ }
48
+ }
49
+ function collectListingTokens(listing) {
50
+ const textParts = [
51
+ listing.title,
52
+ listing.description,
53
+ listing.category,
54
+ ...(listing.tags ?? []),
55
+ ];
56
+ const marketData = listing.marketData ?? {};
57
+ if (listing.marketType === 'info') {
58
+ const infoType = marketData.infoType;
59
+ if (typeof infoType === 'string') {
60
+ textParts.push(infoType);
61
+ }
62
+ const content = marketData.content;
63
+ if (content && typeof content === 'object') {
64
+ const format = content.format;
65
+ if (typeof format === 'string') {
66
+ textParts.push(format);
67
+ }
68
+ }
69
+ }
70
+ if (listing.marketType === 'task') {
71
+ const task = marketData.task;
72
+ if (task) {
73
+ const requirements = task.requirements;
74
+ if (typeof requirements === 'string') {
75
+ textParts.push(requirements);
76
+ }
77
+ const deliverables = task.deliverables;
78
+ if (Array.isArray(deliverables)) {
79
+ for (const entry of deliverables) {
80
+ if (entry && typeof entry === 'object') {
81
+ const name = entry.name;
82
+ if (typeof name === 'string') {
83
+ textParts.push(name);
84
+ }
85
+ }
86
+ }
87
+ }
88
+ }
89
+ }
90
+ if (listing.marketType === 'capability') {
91
+ const capability = marketData.capability;
92
+ if (capability) {
93
+ const name = capability.name;
94
+ if (typeof name === 'string') {
95
+ textParts.push(name);
96
+ }
97
+ const documentation = capability.documentation;
98
+ if (typeof documentation === 'string') {
99
+ textParts.push(documentation);
100
+ }
101
+ }
102
+ }
103
+ const tokens = new Set();
104
+ for (const part of textParts) {
105
+ for (const token of tokenizeText(String(part ?? ''))) {
106
+ tokens.add(token);
107
+ }
108
+ }
109
+ return tokens;
110
+ }
111
+ function extractSkills(listing) {
112
+ if (listing.marketType !== 'task') {
113
+ return [];
114
+ }
115
+ const marketData = listing.marketData ?? {};
116
+ const task = marketData.task;
117
+ if (!task || typeof task !== 'object') {
118
+ return [];
119
+ }
120
+ const skills = task.skills;
121
+ if (!Array.isArray(skills)) {
122
+ return [];
123
+ }
124
+ const result = [];
125
+ for (const entry of skills) {
126
+ if (typeof entry === 'string') {
127
+ result.push(entry.toLowerCase());
128
+ }
129
+ else if (entry && typeof entry === 'object') {
130
+ const name = entry.name;
131
+ if (typeof name === 'string') {
132
+ result.push(name.toLowerCase());
133
+ }
134
+ }
135
+ }
136
+ return result;
137
+ }
138
+ function extractTaskType(listing) {
139
+ if (listing.marketType !== 'task') {
140
+ return null;
141
+ }
142
+ const marketData = listing.marketData ?? {};
143
+ const taskType = marketData.taskType;
144
+ if (typeof taskType === 'string' && taskType.trim().length > 0) {
145
+ return taskType.toLowerCase();
146
+ }
147
+ return null;
148
+ }
149
+ function extractCapabilityType(listing) {
150
+ if (listing.marketType !== 'capability') {
151
+ return null;
152
+ }
153
+ const marketData = listing.marketData ?? {};
154
+ const direct = marketData.capabilityType;
155
+ if (typeof direct === 'string' && direct.trim().length > 0) {
156
+ return direct.toLowerCase();
157
+ }
158
+ const capability = marketData.capability;
159
+ if (capability && typeof capability === 'object') {
160
+ const type = capability.type;
161
+ if (typeof type === 'string' && type.trim().length > 0) {
162
+ return type.toLowerCase();
163
+ }
164
+ }
165
+ return null;
166
+ }
167
+ function extractInfoType(listing) {
168
+ if (listing.marketType !== 'info') {
169
+ return null;
170
+ }
171
+ const marketData = listing.marketData ?? {};
172
+ const infoType = marketData.infoType;
173
+ if (typeof infoType === 'string' && infoType.trim().length > 0) {
174
+ return infoType.toLowerCase();
175
+ }
176
+ return null;
177
+ }
178
+ function extractContentFormat(listing) {
179
+ if (listing.marketType !== 'info') {
180
+ return null;
181
+ }
182
+ const marketData = listing.marketData ?? {};
183
+ const content = marketData.content;
184
+ if (!content || typeof content !== 'object') {
185
+ return null;
186
+ }
187
+ const format = content.format;
188
+ if (typeof format === 'string' && format.trim().length > 0) {
189
+ return format.toLowerCase();
190
+ }
191
+ return null;
192
+ }
193
+ function extractAccessMethodType(listing) {
194
+ if (listing.marketType !== 'info') {
195
+ return null;
196
+ }
197
+ const marketData = listing.marketData ?? {};
198
+ const accessMethod = marketData.accessMethod;
199
+ if (!accessMethod || typeof accessMethod !== 'object') {
200
+ return null;
201
+ }
202
+ const type = accessMethod.type;
203
+ if (typeof type === 'string' && type.trim().length > 0) {
204
+ return type.toLowerCase();
205
+ }
206
+ return null;
207
+ }
208
+ function extractPriceRange(pricing) {
209
+ switch (pricing.type) {
210
+ case 'fixed': {
211
+ if (!pricing.fixedPrice) {
212
+ return null;
213
+ }
214
+ const value = normalizeTokenAmount(pricing.fixedPrice);
215
+ return { min: value, max: value };
216
+ }
217
+ case 'range': {
218
+ if (!pricing.priceRange) {
219
+ return null;
220
+ }
221
+ const min = normalizeTokenAmount(pricing.priceRange.min);
222
+ const max = normalizeTokenAmount(pricing.priceRange.max);
223
+ return { min, max };
224
+ }
225
+ case 'subscription': {
226
+ if (!pricing.subscriptionPrice) {
227
+ return null;
228
+ }
229
+ const value = normalizeTokenAmount(pricing.subscriptionPrice.price);
230
+ return { min: value, max: value };
231
+ }
232
+ case 'usage': {
233
+ if (!pricing.usagePrice) {
234
+ return null;
235
+ }
236
+ const value = normalizeTokenAmount(pricing.usagePrice.pricePerUnit);
237
+ return { min: value, max: value };
238
+ }
239
+ case 'auction': {
240
+ if (!pricing.auction) {
241
+ return null;
242
+ }
243
+ const value = normalizeTokenAmount(pricing.auction.startingPrice);
244
+ return { min: value, max: value };
245
+ }
246
+ default:
247
+ return null;
248
+ }
249
+ }
250
+ function clampPage(value, min, max) {
251
+ if (!Number.isFinite(value)) {
252
+ return min;
253
+ }
254
+ return Math.min(Math.max(Math.trunc(value), min), max);
255
+ }
256
+ export class MarketSearchIndex {
257
+ listings = new Map();
258
+ tokensByListing = new Map();
259
+ tokenIndex = new Map();
260
+ tagIndex = new Map();
261
+ categoryIndex = new Map();
262
+ marketIndex = new Map();
263
+ skillIndex = new Map();
264
+ taskTypeIndex = new Map();
265
+ capabilityIndex = new Map();
266
+ infoTypeIndex = new Map();
267
+ contentFormatIndex = new Map();
268
+ accessMethodIndex = new Map();
269
+ skillByListing = new Map();
270
+ taskTypeByListing = new Map();
271
+ capabilityByListing = new Map();
272
+ infoTypeByListing = new Map();
273
+ contentFormatByListing = new Map();
274
+ accessMethodByListing = new Map();
275
+ static fromState(state) {
276
+ const index = new MarketSearchIndex();
277
+ for (const listing of Object.values(state.listings)) {
278
+ index.indexListing(listing);
279
+ }
280
+ return index;
281
+ }
282
+ indexListing(listing) {
283
+ this.removeListing(listing.id);
284
+ this.listings.set(listing.id, listing);
285
+ const tokens = collectListingTokens(listing);
286
+ this.tokensByListing.set(listing.id, tokens);
287
+ for (const token of tokens) {
288
+ addToIndex(this.tokenIndex, token, listing.id);
289
+ }
290
+ const tags = listing.tags ?? [];
291
+ for (const tag of tags) {
292
+ if (tag.trim().length > 0) {
293
+ addToIndex(this.tagIndex, tag, listing.id);
294
+ }
295
+ }
296
+ if (listing.category) {
297
+ addToIndex(this.categoryIndex, listing.category, listing.id);
298
+ }
299
+ const marketSet = this.marketIndex.get(listing.marketType) ?? new Set();
300
+ marketSet.add(listing.id);
301
+ this.marketIndex.set(listing.marketType, marketSet);
302
+ const skills = extractSkills(listing);
303
+ this.skillByListing.set(listing.id, skills);
304
+ for (const skill of skills) {
305
+ addToIndex(this.skillIndex, skill, listing.id);
306
+ }
307
+ const taskType = extractTaskType(listing);
308
+ this.taskTypeByListing.set(listing.id, taskType);
309
+ if (taskType) {
310
+ addToIndex(this.taskTypeIndex, taskType, listing.id);
311
+ }
312
+ const capabilityType = extractCapabilityType(listing);
313
+ this.capabilityByListing.set(listing.id, capabilityType);
314
+ if (capabilityType) {
315
+ addToIndex(this.capabilityIndex, capabilityType, listing.id);
316
+ }
317
+ const infoType = extractInfoType(listing);
318
+ this.infoTypeByListing.set(listing.id, infoType);
319
+ if (infoType) {
320
+ addToIndex(this.infoTypeIndex, infoType, listing.id);
321
+ }
322
+ const contentFormat = extractContentFormat(listing);
323
+ this.contentFormatByListing.set(listing.id, contentFormat);
324
+ if (contentFormat) {
325
+ addToIndex(this.contentFormatIndex, contentFormat, listing.id);
326
+ }
327
+ const accessMethod = extractAccessMethodType(listing);
328
+ this.accessMethodByListing.set(listing.id, accessMethod);
329
+ if (accessMethod) {
330
+ addToIndex(this.accessMethodIndex, accessMethod, listing.id);
331
+ }
332
+ }
333
+ removeListing(listingId) {
334
+ const listing = this.listings.get(listingId);
335
+ if (!listing) {
336
+ return;
337
+ }
338
+ const tokens = this.tokensByListing.get(listingId) ?? collectListingTokens(listing);
339
+ for (const token of tokens) {
340
+ removeFromIndex(this.tokenIndex, token, listingId);
341
+ }
342
+ this.tokensByListing.delete(listingId);
343
+ for (const tag of listing.tags ?? []) {
344
+ if (tag.trim().length > 0) {
345
+ removeFromIndex(this.tagIndex, tag, listingId);
346
+ }
347
+ }
348
+ if (listing.category) {
349
+ removeFromIndex(this.categoryIndex, listing.category, listingId);
350
+ }
351
+ const marketSet = this.marketIndex.get(listing.marketType);
352
+ if (marketSet) {
353
+ marketSet.delete(listingId);
354
+ if (marketSet.size === 0) {
355
+ this.marketIndex.delete(listing.marketType);
356
+ }
357
+ }
358
+ const skills = this.skillByListing.get(listingId) ?? extractSkills(listing);
359
+ for (const skill of skills) {
360
+ removeFromIndex(this.skillIndex, skill, listingId);
361
+ }
362
+ this.skillByListing.delete(listingId);
363
+ const taskType = this.taskTypeByListing.get(listingId) ?? extractTaskType(listing);
364
+ if (taskType) {
365
+ removeFromIndex(this.taskTypeIndex, taskType, listingId);
366
+ }
367
+ this.taskTypeByListing.delete(listingId);
368
+ const capabilityType = this.capabilityByListing.get(listingId) ?? extractCapabilityType(listing);
369
+ if (capabilityType) {
370
+ removeFromIndex(this.capabilityIndex, capabilityType, listingId);
371
+ }
372
+ this.capabilityByListing.delete(listingId);
373
+ const infoType = this.infoTypeByListing.get(listingId) ?? extractInfoType(listing);
374
+ if (infoType) {
375
+ removeFromIndex(this.infoTypeIndex, infoType, listingId);
376
+ }
377
+ this.infoTypeByListing.delete(listingId);
378
+ const contentFormat = this.contentFormatByListing.get(listingId) ?? extractContentFormat(listing);
379
+ if (contentFormat) {
380
+ removeFromIndex(this.contentFormatIndex, contentFormat, listingId);
381
+ }
382
+ this.contentFormatByListing.delete(listingId);
383
+ const accessMethod = this.accessMethodByListing.get(listingId) ?? extractAccessMethodType(listing);
384
+ if (accessMethod) {
385
+ removeFromIndex(this.accessMethodIndex, accessMethod, listingId);
386
+ }
387
+ this.accessMethodByListing.delete(listingId);
388
+ this.listings.delete(listingId);
389
+ }
390
+ search(query) {
391
+ const page = clampPage(query.page ?? 1, 1, 1_000_000);
392
+ const pageSize = clampPage(query.pageSize ?? 20, 1, 1000);
393
+ const keywordTokens = query.keyword ? tokenizeText(query.keyword) : [];
394
+ let candidateIds = null;
395
+ if (keywordTokens.length > 0) {
396
+ for (const token of keywordTokens) {
397
+ const set = this.tokenIndex.get(token.toLowerCase());
398
+ if (!set) {
399
+ candidateIds = new Set();
400
+ break;
401
+ }
402
+ if (!candidateIds) {
403
+ candidateIds = new Set(set);
404
+ }
405
+ else {
406
+ for (const id of [...candidateIds]) {
407
+ if (!set.has(id)) {
408
+ candidateIds.delete(id);
409
+ }
410
+ }
411
+ }
412
+ }
413
+ }
414
+ if (query.markets && query.markets.length > 0) {
415
+ const marketCandidates = new Set();
416
+ for (const market of query.markets) {
417
+ const set = this.marketIndex.get(market);
418
+ if (set) {
419
+ for (const id of set) {
420
+ marketCandidates.add(id);
421
+ }
422
+ }
423
+ }
424
+ candidateIds = intersect(candidateIds, marketCandidates);
425
+ }
426
+ if (query.category) {
427
+ const set = this.categoryIndex.get(query.category.toLowerCase()) ?? new Set();
428
+ candidateIds = intersect(candidateIds, set);
429
+ }
430
+ if (query.tags && query.tags.length > 0) {
431
+ const tagCandidates = new Set();
432
+ for (const tag of query.tags) {
433
+ const set = this.tagIndex.get(tag.toLowerCase());
434
+ if (set) {
435
+ for (const id of set) {
436
+ tagCandidates.add(id);
437
+ }
438
+ }
439
+ }
440
+ candidateIds = intersect(candidateIds, tagCandidates);
441
+ }
442
+ if (query.skills && query.skills.length > 0) {
443
+ const skillCandidates = new Set();
444
+ for (const skill of query.skills) {
445
+ const set = this.skillIndex.get(skill.toLowerCase());
446
+ if (set) {
447
+ for (const id of set) {
448
+ skillCandidates.add(id);
449
+ }
450
+ }
451
+ }
452
+ candidateIds = intersect(candidateIds, skillCandidates);
453
+ }
454
+ if (query.taskTypes && query.taskTypes.length > 0) {
455
+ const taskCandidates = new Set();
456
+ for (const taskType of query.taskTypes) {
457
+ const set = this.taskTypeIndex.get(taskType.toLowerCase());
458
+ if (set) {
459
+ for (const id of set) {
460
+ taskCandidates.add(id);
461
+ }
462
+ }
463
+ }
464
+ candidateIds = intersect(candidateIds, taskCandidates);
465
+ }
466
+ if (query.capabilityType) {
467
+ const set = this.capabilityIndex.get(query.capabilityType.toLowerCase()) ?? new Set();
468
+ candidateIds = intersect(candidateIds, set);
469
+ }
470
+ if (query.infoTypes && query.infoTypes.length > 0) {
471
+ const infoCandidates = new Set();
472
+ for (const infoType of query.infoTypes) {
473
+ const set = this.infoTypeIndex.get(infoType.toLowerCase());
474
+ if (set) {
475
+ for (const id of set) {
476
+ infoCandidates.add(id);
477
+ }
478
+ }
479
+ }
480
+ candidateIds = intersect(candidateIds, infoCandidates);
481
+ }
482
+ if (query.contentFormats && query.contentFormats.length > 0) {
483
+ const formatCandidates = new Set();
484
+ for (const format of query.contentFormats) {
485
+ const set = this.contentFormatIndex.get(format.toLowerCase());
486
+ if (set) {
487
+ for (const id of set) {
488
+ formatCandidates.add(id);
489
+ }
490
+ }
491
+ }
492
+ candidateIds = intersect(candidateIds, formatCandidates);
493
+ }
494
+ if (query.accessMethods && query.accessMethods.length > 0) {
495
+ const methodCandidates = new Set();
496
+ for (const method of query.accessMethods) {
497
+ const set = this.accessMethodIndex.get(method.toLowerCase());
498
+ if (set) {
499
+ for (const id of set) {
500
+ methodCandidates.add(id);
501
+ }
502
+ }
503
+ }
504
+ candidateIds = intersect(candidateIds, methodCandidates);
505
+ }
506
+ const ids = candidateIds ? [...candidateIds] : [...this.listings.keys()];
507
+ const results = [];
508
+ for (const id of ids) {
509
+ const listing = this.listings.get(id);
510
+ if (!listing) {
511
+ continue;
512
+ }
513
+ if (query.statuses && query.statuses.length > 0) {
514
+ if (!query.statuses.includes(listing.status)) {
515
+ continue;
516
+ }
517
+ }
518
+ if (query.visibility && query.visibility.length > 0) {
519
+ if (!query.visibility.includes(listing.visibility)) {
520
+ continue;
521
+ }
522
+ }
523
+ if (query.minReputation !== undefined && listing.seller.reputation < query.minReputation) {
524
+ continue;
525
+ }
526
+ if (query.minRating !== undefined && listing.stats.averageRating < query.minRating) {
527
+ continue;
528
+ }
529
+ if (query.priceRange) {
530
+ const range = extractPriceRange(listing.pricing);
531
+ if (!range) {
532
+ continue;
533
+ }
534
+ if (query.priceRange.min !== undefined) {
535
+ const min = normalizeTokenAmount(query.priceRange.min);
536
+ if (range.max < min) {
537
+ continue;
538
+ }
539
+ }
540
+ if (query.priceRange.max !== undefined) {
541
+ const max = normalizeTokenAmount(query.priceRange.max);
542
+ if (range.min > max) {
543
+ continue;
544
+ }
545
+ }
546
+ }
547
+ let score;
548
+ if (keywordTokens.length > 0) {
549
+ const tokenSet = this.tokensByListing.get(id) ?? collectListingTokens(listing);
550
+ let matches = 0;
551
+ for (const token of keywordTokens) {
552
+ if (tokenSet.has(token.toLowerCase())) {
553
+ matches += 1;
554
+ }
555
+ }
556
+ score = matches;
557
+ }
558
+ results.push({ ...listing, score });
559
+ }
560
+ const total = results.length;
561
+ const sorted = sortResults(results, query.sort, keywordTokens.length > 0);
562
+ const start = (page - 1) * pageSize;
563
+ const end = start + pageSize;
564
+ const pageItems = sorted.slice(start, end);
565
+ const response = {
566
+ listings: pageItems,
567
+ total,
568
+ page,
569
+ pageSize,
570
+ };
571
+ if (query.includeFacets) {
572
+ response.facets = buildFacets(results);
573
+ }
574
+ return response;
575
+ }
576
+ }
577
+ function sortResults(results, sort, hasKeyword) {
578
+ const mode = sort ?? (hasKeyword ? 'relevance' : 'newest');
579
+ const list = [...results];
580
+ list.sort((a, b) => {
581
+ switch (mode) {
582
+ case 'relevance': {
583
+ const scoreA = a.score ?? 0;
584
+ const scoreB = b.score ?? 0;
585
+ if (scoreA !== scoreB) {
586
+ return scoreB - scoreA;
587
+ }
588
+ return b.createdAt - a.createdAt;
589
+ }
590
+ case 'newest':
591
+ return b.createdAt - a.createdAt;
592
+ case 'price_asc':
593
+ return comparePrice(a.pricing, b.pricing, true);
594
+ case 'price_desc':
595
+ return comparePrice(a.pricing, b.pricing, false);
596
+ case 'rating':
597
+ return b.stats.averageRating - a.stats.averageRating;
598
+ case 'popular':
599
+ return b.stats.orders - a.stats.orders;
600
+ case 'reputation':
601
+ return b.seller.reputation - a.seller.reputation;
602
+ default:
603
+ return 0;
604
+ }
605
+ });
606
+ return list;
607
+ }
608
+ function comparePrice(a, b, asc) {
609
+ const rangeA = extractPriceRange(a);
610
+ const rangeB = extractPriceRange(b);
611
+ if (!rangeA && !rangeB) {
612
+ return 0;
613
+ }
614
+ if (!rangeA) {
615
+ return 1;
616
+ }
617
+ if (!rangeB) {
618
+ return -1;
619
+ }
620
+ const diff = rangeA.min === rangeB.min ? 0 : rangeA.min < rangeB.min ? -1 : 1;
621
+ return asc ? diff : -diff;
622
+ }
623
+ function buildFacets(results) {
624
+ const categoryCounts = new Map();
625
+ const marketCounts = new Map();
626
+ const ratingCounts = new Map();
627
+ for (const listing of results) {
628
+ const categoryKey = listing.category;
629
+ categoryCounts.set(categoryKey, (categoryCounts.get(categoryKey) ?? 0) + 1);
630
+ const marketKey = listing.marketType;
631
+ marketCounts.set(marketKey, (marketCounts.get(marketKey) ?? 0) + 1);
632
+ const rating = listing.stats.averageRating;
633
+ const bucket = rating >= 4.5
634
+ ? '4.5+'
635
+ : rating >= 4
636
+ ? '4+'
637
+ : rating >= 3
638
+ ? '3+'
639
+ : 'below';
640
+ ratingCounts.set(bucket, (ratingCounts.get(bucket) ?? 0) + 1);
641
+ }
642
+ return {
643
+ categories: [...categoryCounts.entries()].map(([key, count]) => ({ key, count })),
644
+ markets: [...marketCounts.entries()].map(([key, count]) => ({ key, count })),
645
+ ratings: [...ratingCounts.entries()].map(([key, count]) => ({ key, count })),
646
+ };
647
+ }
648
+ function intersect(current, next) {
649
+ if (!current) {
650
+ return new Set(next);
651
+ }
652
+ for (const id of [...current]) {
653
+ if (!next.has(id)) {
654
+ current.delete(id);
655
+ }
656
+ }
657
+ return current;
658
+ }
659
+ //# sourceMappingURL=search.js.map