roomzin-js 1.0.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 (171) hide show
  1. package/LICENSE +68 -0
  2. package/README.md +467 -0
  3. package/dist/api/client.d.ts +86 -0
  4. package/dist/api/client.d.ts.map +1 -0
  5. package/dist/api/client.js +3 -0
  6. package/dist/api/client.js.map +1 -0
  7. package/dist/cluster/api.d.ts +34 -0
  8. package/dist/cluster/api.d.ts.map +1 -0
  9. package/dist/cluster/api.js +250 -0
  10. package/dist/cluster/api.js.map +1 -0
  11. package/dist/cluster/config.d.ts +30 -0
  12. package/dist/cluster/config.d.ts.map +1 -0
  13. package/dist/cluster/config.js +86 -0
  14. package/dist/cluster/config.js.map +1 -0
  15. package/dist/cluster/index.d.ts +3 -0
  16. package/dist/cluster/index.d.ts.map +1 -0
  17. package/dist/cluster/index.js +21 -0
  18. package/dist/cluster/index.js.map +1 -0
  19. package/dist/index.d.ts +5 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +21 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/internal/cluster/handler.d.ts +60 -0
  24. package/dist/internal/cluster/handler.d.ts.map +1 -0
  25. package/dist/internal/cluster/handler.js +589 -0
  26. package/dist/internal/cluster/handler.js.map +1 -0
  27. package/dist/internal/cluster/httputil.d.ts +25 -0
  28. package/dist/internal/cluster/httputil.d.ts.map +1 -0
  29. package/dist/internal/cluster/httputil.js +193 -0
  30. package/dist/internal/cluster/httputil.js.map +1 -0
  31. package/dist/internal/command/dec_room_avl.d.ts +5 -0
  32. package/dist/internal/command/dec_room_avl.d.ts.map +1 -0
  33. package/dist/internal/command/dec_room_avl.js +49 -0
  34. package/dist/internal/command/dec_room_avl.js.map +1 -0
  35. package/dist/internal/command/del_prop.d.ts +4 -0
  36. package/dist/internal/command/del_prop.d.ts.map +1 -0
  37. package/dist/internal/command/del_prop.js +43 -0
  38. package/dist/internal/command/del_prop.js.map +1 -0
  39. package/dist/internal/command/del_prop_day.d.ts +5 -0
  40. package/dist/internal/command/del_prop_day.d.ts.map +1 -0
  41. package/dist/internal/command/del_prop_day.js +47 -0
  42. package/dist/internal/command/del_prop_day.js.map +1 -0
  43. package/dist/internal/command/del_prop_room.d.ts +5 -0
  44. package/dist/internal/command/del_prop_room.d.ts.map +1 -0
  45. package/dist/internal/command/del_prop_room.js +46 -0
  46. package/dist/internal/command/del_prop_room.js.map +1 -0
  47. package/dist/internal/command/del_room_day.d.ts +5 -0
  48. package/dist/internal/command/del_room_day.d.ts.map +1 -0
  49. package/dist/internal/command/del_room_day.js +47 -0
  50. package/dist/internal/command/del_room_day.js.map +1 -0
  51. package/dist/internal/command/del_segment.d.ts +4 -0
  52. package/dist/internal/command/del_segment.d.ts.map +1 -0
  53. package/dist/internal/command/del_segment.js +43 -0
  54. package/dist/internal/command/del_segment.js.map +1 -0
  55. package/dist/internal/command/get_codecs.d.ts +5 -0
  56. package/dist/internal/command/get_codecs.d.ts.map +1 -0
  57. package/dist/internal/command/get_codecs.js +38 -0
  58. package/dist/internal/command/get_codecs.js.map +1 -0
  59. package/dist/internal/command/get_prop_room_day.d.ts +7 -0
  60. package/dist/internal/command/get_prop_room_day.d.ts.map +1 -0
  61. package/dist/internal/command/get_prop_room_day.js +59 -0
  62. package/dist/internal/command/get_prop_room_day.js.map +1 -0
  63. package/dist/internal/command/get_segments.d.ts +5 -0
  64. package/dist/internal/command/get_segments.d.ts.map +1 -0
  65. package/dist/internal/command/get_segments.js +47 -0
  66. package/dist/internal/command/get_segments.js.map +1 -0
  67. package/dist/internal/command/inc_room_avl.d.ts +5 -0
  68. package/dist/internal/command/inc_room_avl.d.ts.map +1 -0
  69. package/dist/internal/command/inc_room_avl.js +46 -0
  70. package/dist/internal/command/inc_room_avl.js.map +1 -0
  71. package/dist/internal/command/index.d.ts +20 -0
  72. package/dist/internal/command/index.d.ts.map +1 -0
  73. package/dist/internal/command/index.js +61 -0
  74. package/dist/internal/command/index.js.map +1 -0
  75. package/dist/internal/command/prop_exist.d.ts +4 -0
  76. package/dist/internal/command/prop_exist.d.ts.map +1 -0
  77. package/dist/internal/command/prop_exist.js +43 -0
  78. package/dist/internal/command/prop_exist.js.map +1 -0
  79. package/dist/internal/command/prop_room_date_list.d.ts +5 -0
  80. package/dist/internal/command/prop_room_date_list.d.ts.map +1 -0
  81. package/dist/internal/command/prop_room_date_list.js +50 -0
  82. package/dist/internal/command/prop_room_date_list.js.map +1 -0
  83. package/dist/internal/command/prop_room_exist.d.ts +5 -0
  84. package/dist/internal/command/prop_room_exist.d.ts.map +1 -0
  85. package/dist/internal/command/prop_room_exist.js +44 -0
  86. package/dist/internal/command/prop_room_exist.js.map +1 -0
  87. package/dist/internal/command/prop_room_list.d.ts +4 -0
  88. package/dist/internal/command/prop_room_list.d.ts.map +1 -0
  89. package/dist/internal/command/prop_room_list.js +45 -0
  90. package/dist/internal/command/prop_room_list.js.map +1 -0
  91. package/dist/internal/command/search_avail.d.ts +7 -0
  92. package/dist/internal/command/search_avail.d.ts.map +1 -0
  93. package/dist/internal/command/search_avail.js +129 -0
  94. package/dist/internal/command/search_avail.js.map +1 -0
  95. package/dist/internal/command/search_prop.d.ts +5 -0
  96. package/dist/internal/command/search_prop.d.ts.map +1 -0
  97. package/dist/internal/command/search_prop.js +73 -0
  98. package/dist/internal/command/search_prop.js.map +1 -0
  99. package/dist/internal/command/set_prop.d.ts +5 -0
  100. package/dist/internal/command/set_prop.d.ts.map +1 -0
  101. package/dist/internal/command/set_prop.js +47 -0
  102. package/dist/internal/command/set_prop.js.map +1 -0
  103. package/dist/internal/command/set_room_avl.d.ts +5 -0
  104. package/dist/internal/command/set_room_avl.d.ts.map +1 -0
  105. package/dist/internal/command/set_room_avl.js +46 -0
  106. package/dist/internal/command/set_room_avl.js.map +1 -0
  107. package/dist/internal/command/set_room_pkg.d.ts +5 -0
  108. package/dist/internal/command/set_room_pkg.d.ts.map +1 -0
  109. package/dist/internal/command/set_room_pkg.js +76 -0
  110. package/dist/internal/command/set_room_pkg.js.map +1 -0
  111. package/dist/internal/err.d.ts +16 -0
  112. package/dist/internal/err.d.ts.map +1 -0
  113. package/dist/internal/err.js +39 -0
  114. package/dist/internal/err.js.map +1 -0
  115. package/dist/internal/protocol/frame.d.ts +6 -0
  116. package/dist/internal/protocol/frame.d.ts.map +1 -0
  117. package/dist/internal/protocol/frame.js +118 -0
  118. package/dist/internal/protocol/frame.js.map +1 -0
  119. package/dist/internal/protocol/helpers.d.ts +8 -0
  120. package/dist/internal/protocol/helpers.d.ts.map +1 -0
  121. package/dist/internal/protocol/helpers.js +101 -0
  122. package/dist/internal/protocol/helpers.js.map +1 -0
  123. package/dist/internal/protocol/login.d.ts +2 -0
  124. package/dist/internal/protocol/login.d.ts.map +1 -0
  125. package/dist/internal/protocol/login.js +30 -0
  126. package/dist/internal/protocol/login.js.map +1 -0
  127. package/dist/internal/protocol/types.d.ts +19 -0
  128. package/dist/internal/protocol/types.d.ts.map +1 -0
  129. package/dist/internal/protocol/types.js +8 -0
  130. package/dist/internal/protocol/types.js.map +1 -0
  131. package/dist/internal/single/handler.d.ts +30 -0
  132. package/dist/internal/single/handler.d.ts.map +1 -0
  133. package/dist/internal/single/handler.js +197 -0
  134. package/dist/internal/single/handler.js.map +1 -0
  135. package/dist/single/api.d.ts +38 -0
  136. package/dist/single/api.d.ts.map +1 -0
  137. package/dist/single/api.js +240 -0
  138. package/dist/single/api.js.map +1 -0
  139. package/dist/single/config.d.ts +21 -0
  140. package/dist/single/config.d.ts.map +1 -0
  141. package/dist/single/config.js +64 -0
  142. package/dist/single/config.js.map +1 -0
  143. package/dist/single/index.d.ts +3 -0
  144. package/dist/single/index.d.ts.map +1 -0
  145. package/dist/single/index.js +21 -0
  146. package/dist/single/index.js.map +1 -0
  147. package/dist/types/codecs.d.ts +5 -0
  148. package/dist/types/codecs.d.ts.map +1 -0
  149. package/dist/types/codecs.js +16 -0
  150. package/dist/types/codecs.js.map +1 -0
  151. package/dist/types/discovery.d.ts +7 -0
  152. package/dist/types/discovery.d.ts.map +1 -0
  153. package/dist/types/discovery.js +3 -0
  154. package/dist/types/discovery.js.map +1 -0
  155. package/dist/types/err.d.ts +20 -0
  156. package/dist/types/err.d.ts.map +1 -0
  157. package/dist/types/err.js +38 -0
  158. package/dist/types/err.js.map +1 -0
  159. package/dist/types/index.d.ts +5 -0
  160. package/dist/types/index.d.ts.map +1 -0
  161. package/dist/types/index.js +21 -0
  162. package/dist/types/index.js.map +1 -0
  163. package/dist/types/request.d.ts +94 -0
  164. package/dist/types/request.d.ts.map +1 -0
  165. package/dist/types/request.js +207 -0
  166. package/dist/types/request.js.map +1 -0
  167. package/dist/types/response.d.ts +22 -0
  168. package/dist/types/response.d.ts.map +1 -0
  169. package/dist/types/response.js +3 -0
  170. package/dist/types/response.js.map +1 -0
  171. package/package.json +34 -0
package/LICENSE ADDED
@@ -0,0 +1,68 @@
1
+ Business Source License 1.1
2
+
3
+ Licensor: m-javani (or your company name)
4
+
5
+ Licensed Work: Roomzin Go SDK
6
+ The Licensed Work is (c) 2024 m-javani (or your company)
7
+
8
+ Additional Use Grant: You may use the Licensed Work in production
9
+ provided that your use does not include offering the Licensed Work
10
+ as a service to third parties, or creating a derivative work that
11
+ is offered as a service to third parties.
12
+
13
+ Change Date: 2030-01-01
14
+
15
+ Change License: GNU General Public License v3.0 or later
16
+
17
+ Terms:
18
+
19
+ The Licensor hereby grants you the right to copy, modify, create derivative
20
+ works, redistribute, and make non-production use of the Licensed Work. The
21
+ Licensor may make an Additional Use Grant, above, permitting limited
22
+ production use.
23
+
24
+ Effective on the Change Date, or the fourth anniversary of the first publicly
25
+ available distribution of a specific version of the Licensed Work under this
26
+ License, whichever comes first, the Licensor hereby grants you rights under
27
+ the terms of the Change License, and the rights granted in the paragraph
28
+ above terminate.
29
+
30
+ If your use of the Licensed Work does not comply with the requirements
31
+ currently in effect as described in this License, you must purchase a
32
+ commercial license from the Licensor, its affiliated entities, or authorized
33
+ resellers, or you must refrain from using the Licensed Work.
34
+
35
+ All copies of the original and modified Licensed Work, and derivative works
36
+ of the Licensed Work, are subject to this License. This License applies
37
+ separately for each version of the Licensed Work and the Change Date may
38
+ vary for each version of the Licensed Work.
39
+
40
+ Permission is hereby granted, free of charge, to any person obtaining a copy
41
+ of this Licensed Work (the "Software"), to use, copy, modify, merge, publish,
42
+ and/or distribute copies of the Software, subject to the conditions:
43
+
44
+ 1. Redistributions of source code must retain the above copyright notice,
45
+ this list of conditions and the following disclaimers.
46
+
47
+ 2. Redistributions in binary form must reproduce the above copyright notice,
48
+ this list of conditions and the following disclaimers in the documentation
49
+ and/or other materials provided with the distribution.
50
+
51
+ 3. Neither the names of the Licensor, nor the names of its contributors
52
+ may be used to endorse or promote products derived from this Software
53
+ without specific prior written permission.
54
+
55
+ 4. You must not use the Software in any manner that is primarily intended for
56
+ or directed toward commercial advantage or private monetary compensation,
57
+ unless you have obtained a commercial license from the Licensor.
58
+
59
+ Disclaimer of Warranty. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
60
+ ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
61
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
62
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
63
+ DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR
64
+ OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE
65
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
66
+
67
+ THE LICENSOR DOES NOT PROVIDE ANY SUPPORT FOR THE LICENSED WORK, EXCEPT AS
68
+ EXPRESSLY STATED IN A SEPARATE AGREEMENT.
package/README.md ADDED
@@ -0,0 +1,467 @@
1
+ # Roomzin Node.js SDK
2
+
3
+ Official Node.js SDK for [Roomzin](https://m-javani.github.io/roomzin-doc/) — a high-performance in-memory inventory engine for booking platforms.
4
+
5
+ The SDK provides a modern TypeScript API for communicating with Roomzin servers in both standalone and clustered deployments. It automatically manages routing, failover, connection pooling, and cluster topology changes.
6
+
7
+ ---
8
+
9
+ ## Features
10
+
11
+ - Automatic request routing (leader for writes, followers for reads)
12
+ - Built-in failover and cluster discovery
13
+ - Connection pooling
14
+ - Standalone and clustered deployment support
15
+ - Fully typed TypeScript API
16
+ - Promise-based asynchronous API
17
+ - Reusable, concurrency-safe client
18
+
19
+ ---
20
+
21
+ ## Requirements
22
+
23
+ - Node.js 18 or later
24
+ - Roomzin Server v1.x
25
+
26
+ ---
27
+
28
+ ## Installation
29
+
30
+ ```bash
31
+ npm install roomzin-js
32
+ # or
33
+ yarn add roomzin-js
34
+ # or
35
+ pnpm add roomzin-js
36
+ ```
37
+
38
+ ---
39
+
40
+ ## Client Setup
41
+
42
+ ### Standalone
43
+
44
+ ```typescript
45
+ import { SingleClient } from 'roomzin-js';
46
+
47
+ const client = await SingleClient.create({
48
+ host: '127.0.0.1',
49
+ tcpPort: 7777,
50
+ authToken: 'abc123',
51
+ timeout: 5000, // 5 seconds
52
+ keepAlive: 30000, // 30 seconds
53
+ });
54
+
55
+ // Use client...
56
+ await client.close();
57
+ ```
58
+
59
+ ### Cluster (Static Discovery)
60
+
61
+ ```typescript
62
+ import { ClusterClient, ClusterConfigBuilder } from 'roomzin-js';
63
+ import type { NodeAddr } from 'roomzin-js';
64
+
65
+ const staticDiscovery: NodeAddr[] = [
66
+ { node_id: 'roomzin-0', addr: '172.20.0.10', tcp_port: 7777, api_port: 8080 },
67
+ { node_id: 'roomzin-1', addr: '172.20.0.11', tcp_port: 7777, api_port: 8080 },
68
+ { node_id: 'roomzin-2', addr: '172.20.0.12', tcp_port: 7777, api_port: 8080 },
69
+ ];
70
+
71
+ const cfg = ClusterConfigBuilder.new()
72
+ .withSeedNodeIds('roomzin-0,roomzin-1,roomzin-2')
73
+ .withStaticDiscovery(staticDiscovery)
74
+ .withAPIPort(8080)
75
+ .withTCPPort(7777)
76
+ .withToken('abc123')
77
+ .withTimeout(5000)
78
+ .withHttpTimeout(5000)
79
+ .withKeepAlive(30000)
80
+ .withMaxActiveConns(100)
81
+ .build();
82
+
83
+ const client = await ClusterClient.create(cfg);
84
+ await client.close();
85
+ ```
86
+
87
+ ### Cluster (HTTP Discovery)
88
+
89
+ ```typescript
90
+ const cfg = ClusterConfigBuilder.new()
91
+ .withSeedNodeIds('roomzin-0,roomzin-1,roomzin-2')
92
+ .withHTTPDiscovery('http://discovery-service:8080/nodes')
93
+ .withAPIPort(8080)
94
+ .withTCPPort(7777)
95
+ .withToken('abc123')
96
+ .withTimeout(5000)
97
+ .withHttpTimeout(5000)
98
+ .withKeepAlive(30000)
99
+ .build();
100
+
101
+ const client = await ClusterClient.create(cfg);
102
+ ```
103
+
104
+ ---
105
+
106
+ ## Discovery Configuration
107
+
108
+ Roomzin SDKs need to know how to reach each Roomzin node in the cluster. The cluster nodes communicate with each other using internal address resolvers, but the SDK as an external client needs actual network addresses (IP:port or hostname:port) to connect.
109
+
110
+ The SDK fetches the cluster topology from the Roomzin cluster itself. This topology includes the node identities of the leader and followers. The SDK then uses discovery to resolve these node identities into actual network addresses.
111
+
112
+ Two discovery modes are supported:
113
+
114
+ ### Static Discovery
115
+
116
+ The SDK gets the mapping once in config and never updates it. Use this when your cluster nodes have stable, predictable addresses.
117
+
118
+ ### HTTP Discovery
119
+
120
+ The SDK periodically fetches the mapping from an HTTP endpoint. Use this when cluster nodes are dynamic (e.g., Kubernetes pods with changing IPs).
121
+
122
+ ---
123
+
124
+ ## Property Management
125
+
126
+ ### setProp
127
+ Adds or updates a property.
128
+
129
+ ```typescript
130
+ await client.setProp({
131
+ segment: 'downtown',
132
+ area: 'manhattan',
133
+ propertyID: 'hotel_123',
134
+ propertyType: 'hotel',
135
+ category: 'luxury',
136
+ stars: 4,
137
+ latitude: 40.7128,
138
+ longitude: -74.0060,
139
+ amenities: ['wifi', 'pool', 'gym'],
140
+ });
141
+ ```
142
+
143
+ ### searchProp
144
+ Searches properties by segment, area, type, or location.
145
+
146
+ ```typescript
147
+ // By segment
148
+ const ids = await client.searchProp({ segment: 'downtown' });
149
+
150
+ // By area
151
+ const ids = await client.searchProp({
152
+ segment: 'downtown',
153
+ area: 'manhattan',
154
+ });
155
+
156
+ // By location (radius search)
157
+ const ids = await client.searchProp({
158
+ segment: 'downtown',
159
+ latitude: 40.7128,
160
+ longitude: -74.0060,
161
+ });
162
+ ```
163
+
164
+ ### propExist
165
+ Checks if a property exists.
166
+
167
+ ```typescript
168
+ const exists = await client.propExist('hotel_123');
169
+ ```
170
+
171
+ ### propRoomExist
172
+ Checks if a specific room type exists for a property.
173
+
174
+ ```typescript
175
+ const exists = await client.propRoomExist({
176
+ propertyID: 'hotel_123',
177
+ roomType: 'suite',
178
+ });
179
+ ```
180
+
181
+ ### propRoomList
182
+ Lists all room types for a property.
183
+
184
+ ```typescript
185
+ const rooms = await client.propRoomList('hotel_123');
186
+ ```
187
+
188
+ ### propRoomDateList
189
+ Lists dates with availability data for a property and room type.
190
+
191
+ ```typescript
192
+ const dates = await client.propRoomDateList({
193
+ propertyID: 'hotel_123',
194
+ roomType: 'suite',
195
+ });
196
+ ```
197
+
198
+ ---
199
+
200
+ ## Room Package Management
201
+
202
+ ### setRoomPkg
203
+ Sets availability, price, and rate features for a room type on a date.
204
+
205
+ ```typescript
206
+ await client.setRoomPkg({
207
+ propertyID: 'hotel_123',
208
+ roomType: 'suite',
209
+ date: '2026-07-20',
210
+ availability: 10,
211
+ finalPrice: 199,
212
+ rateFeature: ['free_cancellation', 'breakfast_included'],
213
+ });
214
+ ```
215
+
216
+ ### setRoomAvl
217
+ Sets exact availability for a room type on a specific date.
218
+
219
+ ```typescript
220
+ const newAvail = await client.setRoomAvl({
221
+ propertyID: 'hotel_123',
222
+ roomType: 'suite',
223
+ date: '2026-07-20',
224
+ amount: 20,
225
+ });
226
+ ```
227
+
228
+ ### incRoomAvl
229
+ Increases availability (e.g., on cancellation).
230
+
231
+ ```typescript
232
+ const newAvail = await client.incRoomAvl({
233
+ propertyID: 'hotel_123',
234
+ roomType: 'suite',
235
+ date: '2026-07-20',
236
+ amount: 1,
237
+ });
238
+ ```
239
+
240
+ ### decRoomAvl
241
+ Decreases availability (e.g., on booking).
242
+
243
+ ```typescript
244
+ const newAvail = await client.decRoomAvl({
245
+ propertyID: 'hotel_123',
246
+ roomType: 'suite',
247
+ date: '2026-07-20',
248
+ amount: 2,
249
+ });
250
+ ```
251
+
252
+ ### getPropRoomDay
253
+ Gets availability and pricing for a specific room on a specific date.
254
+
255
+ ```typescript
256
+ const day = await client.getPropRoomDay({
257
+ propertyID: 'hotel_123',
258
+ roomType: 'suite',
259
+ date: '2026-07-20',
260
+ });
261
+ console.log(`Avail: ${day.availability}, Price: ${day.finalPrice}`);
262
+ ```
263
+
264
+ ---
265
+
266
+ ## Search & Query
267
+
268
+ ### searchAvail
269
+ Searches available rooms by filters.
270
+
271
+ ```typescript
272
+ const results = await client.searchAvail({
273
+ segment: 'downtown',
274
+ roomType: 'suite',
275
+ date: ['2026-07-20', '2026-07-21'],
276
+ limit: 50,
277
+ minPrice: 100,
278
+ maxPrice: 300,
279
+ amenities: ['wifi', 'pool'],
280
+ rateFeature: ['free_cancellation'],
281
+ });
282
+
283
+ for (const result of results) {
284
+ console.log(`Property: ${result.propertyID}`);
285
+ for (const day of result.days) {
286
+ console.log(` ${day.date}: Avail ${day.availability}, Price ${day.finalPrice}`);
287
+ }
288
+ }
289
+ ```
290
+
291
+ ### getSegments
292
+ Lists all active segments with their property counts.
293
+
294
+ ```typescript
295
+ const segments = await client.getSegments();
296
+ for (const seg of segments) {
297
+ console.log(`${seg.segment}: ${seg.count} properties`);
298
+ }
299
+ ```
300
+
301
+ ### getCodecs
302
+ Gets the current codec registry (used internally for validation).
303
+
304
+ ```typescript
305
+ const codecs = await client.getCodecs();
306
+ console.log(codecs.rateFeatures);
307
+ ```
308
+
309
+ ---
310
+
311
+ ## Delete Operations
312
+
313
+ ### delRoomDay
314
+ Deletes availability for a specific room on a specific date.
315
+
316
+ ```typescript
317
+ await client.delRoomDay({
318
+ propertyID: 'hotel_123',
319
+ roomType: 'suite',
320
+ date: '2026-07-20',
321
+ });
322
+ ```
323
+
324
+ ### delPropDay
325
+ Deletes all data for a property on a specific date.
326
+
327
+ ```typescript
328
+ await client.delPropDay({
329
+ propertyID: 'hotel_123',
330
+ date: '2026-07-20',
331
+ });
332
+ ```
333
+
334
+ ### delPropRoom
335
+ Deletes a room type from a property.
336
+
337
+ ```typescript
338
+ await client.delPropRoom({
339
+ propertyID: 'hotel_123',
340
+ roomType: 'suite',
341
+ });
342
+ ```
343
+
344
+ ### delProp
345
+ Deletes an entire property.
346
+
347
+ ```typescript
348
+ await client.delProp('hotel_123');
349
+ ```
350
+
351
+ ### delSegment
352
+ Deletes a segment and all properties within it.
353
+
354
+ ```typescript
355
+ await client.delSegment('downtown');
356
+ ```
357
+
358
+ ---
359
+
360
+ ## Error Handling
361
+
362
+ Every SDK operation may reject with a `RoomzinError`. Use the provided helper functions to classify errors:
363
+
364
+ ```typescript
365
+ import { IsRequest, IsRetry, IsClient, IsInternal } from 'roomzin-js';
366
+
367
+ try {
368
+ await client.setRoomPkg(payload);
369
+ } catch (err) {
370
+ if (IsRequest(err)) {
371
+ // Business rule violation - fix the request
372
+ console.log('Request error:', err.code);
373
+ } else if (IsRetry(err)) {
374
+ // Temporary condition - retry with backoff
375
+ await sleep(100);
376
+ await client.setRoomPkg(payload);
377
+ } else if (IsClient(err)) {
378
+ // Authentication or protocol errors
379
+ console.log('Client error:', err.message);
380
+ } else if (IsInternal(err)) {
381
+ // Unexpected server response
382
+ throw new Error('Internal error', { cause: err });
383
+ } else {
384
+ // Fatal error
385
+ throw err;
386
+ }
387
+ }
388
+ ```
389
+
390
+ ### Error Categories
391
+
392
+ | Category | Description | Action |
393
+ |----------|-------------|--------|
394
+ | **Client** | Authentication or protocol errors | Check credentials and configuration |
395
+ | **Request** | Invalid input or business rule violation | Fix request, don't retry |
396
+ | **Retry** | Temporary server condition (429, 503, 308) | Retry with backoff |
397
+ | **Internal** | Unexpected server response | Log and investigate |
398
+
399
+ ---
400
+
401
+ ## Client Lifecycle
402
+
403
+ Create a **single client** during application startup and reuse it throughout your application.
404
+
405
+ ```typescript
406
+ // ✅ Good - create once, reuse
407
+ const client = await SingleClient.create(config);
408
+ // Use client everywhere...
409
+ await client.close();
410
+
411
+ // ❌ Bad - creating per request
412
+ for (const req of requests) {
413
+ const client = await SingleClient.create(config); // Don't do this
414
+ await client.setRoomPkg(req);
415
+ await client.close();
416
+ }
417
+ ```
418
+
419
+ The client is safe for concurrent use and manages TCP connections internally.
420
+
421
+ ---
422
+
423
+ ## API Reference
424
+
425
+ For the complete interface definition, see [`src/api/client.ts`](src/api/client.ts). All types are documented with JSDoc comments.
426
+
427
+ ---
428
+
429
+ ## Documentation
430
+
431
+ For Roomzin concepts, deployment, and administration:
432
+
433
+ [https://m-javani.github.io/roomzin-doc/docs.html](https://m-javani.github.io/roomzin-doc/docs.html)
434
+
435
+ ---
436
+
437
+ ## Contributing
438
+
439
+ Contributions are welcome! Please open an issue before proposing large changes.
440
+
441
+ All contributions are subject to the BUSL-1.1 License terms.
442
+
443
+ ---
444
+
445
+ ## License
446
+
447
+ This SDK is licensed under the [BUSL-1.1 License](LICENSE).
448
+
449
+ **Note:** This SDK communicates with Roomzin Server, which requires a valid Roomzin license.
450
+
451
+ ---
452
+
453
+ ## Support
454
+
455
+ - **Documentation**: [roomzin-doc](https://m-javani.github.io/roomzin-doc/)
456
+ - **Community Q&A**: [GitHub Discussions](https://github.com/m-javani/roomzin-doc/discussions)
457
+ - **Issues**: [GitHub Issues](https://github.com/roomzin/roomzin-js/issues)
458
+ - **Security**: [mehdy.javany@gmail.com](mailto:mehdy.javany@gmail.com)
459
+
460
+ ---
461
+
462
+ ## Related Repositories
463
+
464
+ - [Roomzin Quickstart](https://github.com/m-javani/roomzin-quickstart) — Local Docker cluster
465
+ - [Roomzin Bench](https://github.com/m-javani/roomzin-bench) — Benchmarking tool
466
+
467
+ ---
@@ -0,0 +1,86 @@
1
+ import type { PropertyAvail, GetRoomDayResult, SegmentInfo } from '../types/response';
2
+ import type { Codecs } from '../types/codecs';
3
+ import type { SetPropPayload, SearchPropPayload, SearchAvailPayload, SetRoomPkgPayload, UpdRoomAvlPayload, PropRoomExistPayload, PropRoomDateListPayload, DelPropDayRequest, DelPropRoomPayload, DelRoomDayRequest, GetRoomDayRequest } from '../types/request';
4
+ export interface CacheClientAPI {
5
+ /**
6
+ * Returns the current codec registry (field IDs, compression, etc.)
7
+ */
8
+ getCodecs(): Promise<Codecs>;
9
+ /**
10
+ * Set property metadata
11
+ */
12
+ setProp(p: SetPropPayload): Promise<void>;
13
+ /**
14
+ * Search properties by filters
15
+ */
16
+ searchProp(p: SearchPropPayload): Promise<string[]>;
17
+ /**
18
+ * Search availability across properties/dates
19
+ */
20
+ searchAvail(p: SearchAvailPayload): Promise<PropertyAvail[]>;
21
+ /**
22
+ * Assign a package/pricing to a room type
23
+ */
24
+ setRoomPkg(p: SetRoomPkgPayload): Promise<void>;
25
+ /**
26
+ * Absolute set of room availability
27
+ */
28
+ setRoomAvl(p: UpdRoomAvlPayload): Promise<number>;
29
+ /**
30
+ * Increment room availability (e.g. on cancellation)
31
+ */
32
+ incRoomAvl(p: UpdRoomAvlPayload): Promise<number>;
33
+ /**
34
+ * Decrement room availability (e.g. on booking)
35
+ */
36
+ decRoomAvl(p: UpdRoomAvlPayload): Promise<number>;
37
+ /**
38
+ * Check if property exists
39
+ */
40
+ propExist(propertyID: string): Promise<boolean>;
41
+ /**
42
+ * Check if specific room type exists in property
43
+ */
44
+ propRoomExist(p: PropRoomExistPayload): Promise<boolean>;
45
+ /**
46
+ * List all room type IDs for a property
47
+ */
48
+ propRoomList(propertyID: string): Promise<string[]>;
49
+ /**
50
+ * List dates that have availability data for a property+room
51
+ */
52
+ propRoomDateList(p: PropRoomDateListPayload): Promise<string[]>;
53
+ /**
54
+ * Delete entire property
55
+ */
56
+ delProp(propertyID: string): Promise<void>;
57
+ /**
58
+ * Delete a segment (rate plan, channel, etc.)
59
+ */
60
+ delSegment(segment: string): Promise<void>;
61
+ /**
62
+ * Delete all data for a property on a specific date
63
+ */
64
+ delPropDay(p: DelPropDayRequest): Promise<void>;
65
+ /**
66
+ * Delete a room type from a property
67
+ */
68
+ delPropRoom(p: DelPropRoomPayload): Promise<void>;
69
+ /**
70
+ * Delete availability for a specific room+date
71
+ */
72
+ delRoomDay(p: DelRoomDayRequest): Promise<void>;
73
+ /**
74
+ * Get availability & pricing for a specific room+date
75
+ */
76
+ getPropRoomDay(p: GetRoomDayRequest): Promise<GetRoomDayResult>;
77
+ /**
78
+ * List all active segments
79
+ */
80
+ getSegments(): Promise<SegmentInfo[]>;
81
+ /**
82
+ * Close connection and release resources
83
+ */
84
+ close(): Promise<void>;
85
+ }
86
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,aAAa,EACb,gBAAgB,EAChB,WAAW,EACd,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EACR,MAAM,EACT,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EACR,cAAc,EACd,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,uBAAuB,EACvB,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACpB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,WAAW,cAAc;IAC3B;;OAEG;IACH,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAE7B;;OAEG;IACH,OAAO,CAAC,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1C;;OAEG;IACH,UAAU,CAAC,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAEpD;;OAEG;IACH,WAAW,CAAC,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IAE7D;;OAEG;IACH,UAAU,CAAC,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhD;;OAEG;IACH,UAAU,CAAC,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAElD;;OAEG;IACH,UAAU,CAAC,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAElD;;OAEG;IACH,UAAU,CAAC,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAElD;;OAEG;IACH,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEhD;;OAEG;IACH,aAAa,CAAC,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEzD;;OAEG;IACH,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAEpD;;OAEG;IACH,gBAAgB,CAAC,CAAC,EAAE,uBAAuB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAEhE;;OAEG;IACH,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE3C;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE3C;;OAEG;IACH,UAAU,CAAC,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhD;;OAEG;IACH,WAAW,CAAC,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAElD;;OAEG;IACH,UAAU,CAAC,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhD;;OAEG;IACH,cAAc,CAAC,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAEhE;;OAEG;IACH,WAAW,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAEtC;;OAEG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":""}
@@ -0,0 +1,34 @@
1
+ import type { ClusterConfig } from './config';
2
+ import type { CacheClientAPI } from '../api/client';
3
+ import type { Codecs } from '../types/codecs';
4
+ import { DelPropDayRequest, DelPropRoomPayload, DelRoomDayRequest, GetRoomDayRequest, PropRoomDateListPayload, PropRoomExistPayload, SearchAvailPayload, SearchPropPayload, SetPropPayload, SetRoomPkgPayload, UpdRoomAvlPayload } from '../types/request';
5
+ export declare class Client implements CacheClientAPI {
6
+ private handler;
7
+ private codecs;
8
+ private constructor();
9
+ static create(cfg: ClusterConfig): Promise<Client>;
10
+ private getCodecsInternal;
11
+ private fetchCodecs;
12
+ private assertOk;
13
+ getCodecs(): Promise<Codecs>;
14
+ setProp(p: SetPropPayload): Promise<void>;
15
+ setRoomPkg(p: SetRoomPkgPayload): Promise<void>;
16
+ setRoomAvl(p: UpdRoomAvlPayload): Promise<number>;
17
+ incRoomAvl(p: UpdRoomAvlPayload): Promise<number>;
18
+ decRoomAvl(p: UpdRoomAvlPayload): Promise<number>;
19
+ searchProp(p: SearchPropPayload): Promise<string[]>;
20
+ searchAvail(p: SearchAvailPayload): Promise<any[]>;
21
+ propExist(propertyID: string): Promise<boolean>;
22
+ propRoomExist(p: PropRoomExistPayload): Promise<boolean>;
23
+ propRoomList(propertyID: string): Promise<string[]>;
24
+ propRoomDateList(p: PropRoomDateListPayload): Promise<string[]>;
25
+ delProp(propertyID: string): Promise<void>;
26
+ delSegment(segment: string): Promise<void>;
27
+ delPropDay(p: DelPropDayRequest): Promise<void>;
28
+ delPropRoom(p: DelPropRoomPayload): Promise<void>;
29
+ delRoomDay(p: DelRoomDayRequest): Promise<void>;
30
+ getPropRoomDay(p: GetRoomDayRequest): Promise<any>;
31
+ getSegments(): Promise<any[]>;
32
+ close(): Promise<void>;
33
+ }
34
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/cluster/api.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AA4C9C,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,cAAc,EAAE,iBAAiB,EAAE,iBAAiB,EAAwM,MAAM,kBAAkB,CAAC;AAIjc,qBAAa,MAAO,YAAW,cAAc;IACzC,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,MAAM,CAAuB;IAErC,OAAO;WASM,MAAM,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC;YAmC1C,iBAAiB;YAQjB,WAAW;IAWzB,OAAO,CAAC,QAAQ;IAYV,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC;IAM5B,OAAO,CAAC,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAYzC,UAAU,CAAC,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAY/C,UAAU,CAAC,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC;IAUjD,UAAU,CAAC,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC;IAUjD,UAAU,CAAC,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC;IAUjD,UAAU,CAAC,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAWnD,WAAW,CAAC,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAWlD,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAQ/C,aAAa,CAAC,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,OAAO,CAAC;IAUxD,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAQnD,gBAAgB,CAAC,CAAC,EAAE,uBAAuB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAU/D,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAS1C,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ1C,UAAU,CAAC,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAU/C,WAAW,CAAC,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAUjD,UAAU,CAAC,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAU/C,cAAc,CAAC,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,GAAG,CAAC;IAWlD,WAAW,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAO7B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG/B"}