@comapeo/core 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 (186) hide show
  1. package/LICENSE.md +9 -0
  2. package/README.md +31 -0
  3. package/dist/blob-api.d.ts +92 -0
  4. package/dist/blob-api.d.ts.map +1 -0
  5. package/dist/blob-store/index.d.ts +163 -0
  6. package/dist/blob-store/index.d.ts.map +1 -0
  7. package/dist/blob-store/live-download.d.ts +107 -0
  8. package/dist/blob-store/live-download.d.ts.map +1 -0
  9. package/dist/config-import.d.ts +74 -0
  10. package/dist/config-import.d.ts.map +1 -0
  11. package/dist/constants.d.ts +14 -0
  12. package/dist/constants.d.ts.map +1 -0
  13. package/dist/core-manager/bitfield-rle.d.ts +25 -0
  14. package/dist/core-manager/bitfield-rle.d.ts.map +1 -0
  15. package/dist/core-manager/core-index.d.ts +56 -0
  16. package/dist/core-manager/core-index.d.ts.map +1 -0
  17. package/dist/core-manager/index.d.ts +125 -0
  18. package/dist/core-manager/index.d.ts.map +1 -0
  19. package/dist/core-manager/random-access-file-pool.d.ts +17 -0
  20. package/dist/core-manager/random-access-file-pool.d.ts.map +1 -0
  21. package/dist/core-manager/remote-bitfield.d.ts +146 -0
  22. package/dist/core-manager/remote-bitfield.d.ts.map +1 -0
  23. package/dist/core-ownership.d.ts +112 -0
  24. package/dist/core-ownership.d.ts.map +1 -0
  25. package/dist/datastore/index.d.ts +91 -0
  26. package/dist/datastore/index.d.ts.map +1 -0
  27. package/dist/datatype/index.d.ts +108 -0
  28. package/dist/discovery/local-discovery.d.ts +64 -0
  29. package/dist/discovery/local-discovery.d.ts.map +1 -0
  30. package/dist/errors.d.ts +4 -0
  31. package/dist/errors.d.ts.map +1 -0
  32. package/dist/fastify-controller.d.ts +27 -0
  33. package/dist/fastify-controller.d.ts.map +1 -0
  34. package/dist/fastify-plugins/blobs.d.ts +6 -0
  35. package/dist/fastify-plugins/blobs.d.ts.map +1 -0
  36. package/dist/fastify-plugins/constants.d.ts +3 -0
  37. package/dist/fastify-plugins/constants.d.ts.map +1 -0
  38. package/dist/fastify-plugins/icons.d.ts +6 -0
  39. package/dist/fastify-plugins/icons.d.ts.map +1 -0
  40. package/dist/fastify-plugins/maps/index.d.ts +11 -0
  41. package/dist/fastify-plugins/maps/index.d.ts.map +1 -0
  42. package/dist/fastify-plugins/maps/offline-fallback-map.d.ts +12 -0
  43. package/dist/fastify-plugins/maps/offline-fallback-map.d.ts.map +1 -0
  44. package/dist/fastify-plugins/maps/static-maps.d.ts +11 -0
  45. package/dist/fastify-plugins/maps/static-maps.d.ts.map +1 -0
  46. package/dist/fastify-plugins/utils.d.ts +23 -0
  47. package/dist/fastify-plugins/utils.d.ts.map +1 -0
  48. package/dist/generated/extensions.d.ts +44 -0
  49. package/dist/generated/extensions.d.ts.map +1 -0
  50. package/dist/generated/keys.d.ts +36 -0
  51. package/dist/generated/keys.d.ts.map +1 -0
  52. package/dist/generated/rpc.d.ts +87 -0
  53. package/dist/generated/rpc.d.ts.map +1 -0
  54. package/dist/icon-api.d.ts +109 -0
  55. package/dist/icon-api.d.ts.map +1 -0
  56. package/dist/index-writer/index.d.ts +51 -0
  57. package/dist/index-writer/index.d.ts.map +1 -0
  58. package/dist/index.d.ts +14 -0
  59. package/dist/index.d.ts.map +1 -0
  60. package/dist/invite-api.d.ts +70 -0
  61. package/dist/invite-api.d.ts.map +1 -0
  62. package/dist/lib/hashmap.d.ts +62 -0
  63. package/dist/lib/hashmap.d.ts.map +1 -0
  64. package/dist/lib/hypercore-helpers.d.ts +6 -0
  65. package/dist/lib/hypercore-helpers.d.ts.map +1 -0
  66. package/dist/lib/noise-secret-stream-helpers.d.ts +45 -0
  67. package/dist/lib/noise-secret-stream-helpers.d.ts.map +1 -0
  68. package/dist/lib/ponyfills.d.ts +10 -0
  69. package/dist/lib/ponyfills.d.ts.map +1 -0
  70. package/dist/lib/string.d.ts +2 -0
  71. package/dist/lib/string.d.ts.map +1 -0
  72. package/dist/lib/timing-safe-equal.d.ts +15 -0
  73. package/dist/lib/timing-safe-equal.d.ts.map +1 -0
  74. package/dist/local-peers.d.ts +151 -0
  75. package/dist/local-peers.d.ts.map +1 -0
  76. package/dist/logger.d.ts +32 -0
  77. package/dist/logger.d.ts.map +1 -0
  78. package/dist/mapeo-manager.d.ts +178 -0
  79. package/dist/mapeo-manager.d.ts.map +1 -0
  80. package/dist/mapeo-project.d.ts +3233 -0
  81. package/dist/mapeo-project.d.ts.map +1 -0
  82. package/dist/member-api.d.ts +114 -0
  83. package/dist/member-api.d.ts.map +1 -0
  84. package/dist/roles.d.ts +157 -0
  85. package/dist/roles.d.ts.map +1 -0
  86. package/dist/schema/client.d.ts +284 -0
  87. package/dist/schema/client.d.ts.map +1 -0
  88. package/dist/schema/project.d.ts +1812 -0
  89. package/dist/schema/project.d.ts.map +1 -0
  90. package/dist/schema/schema-to-drizzle.d.ts +20 -0
  91. package/dist/schema/schema-to-drizzle.d.ts.map +1 -0
  92. package/dist/schema/types.d.ts +98 -0
  93. package/dist/schema/types.d.ts.map +1 -0
  94. package/dist/schema/utils.d.ts +55 -0
  95. package/dist/schema/utils.d.ts.map +1 -0
  96. package/dist/sync/core-sync-state.d.ts +252 -0
  97. package/dist/sync/core-sync-state.d.ts.map +1 -0
  98. package/dist/sync/namespace-sync-state.d.ts +47 -0
  99. package/dist/sync/namespace-sync-state.d.ts.map +1 -0
  100. package/dist/sync/peer-sync-controller.d.ts +44 -0
  101. package/dist/sync/peer-sync-controller.d.ts.map +1 -0
  102. package/dist/sync/sync-api.d.ts +158 -0
  103. package/dist/sync/sync-api.d.ts.map +1 -0
  104. package/dist/sync/sync-state.d.ts +40 -0
  105. package/dist/sync/sync-state.d.ts.map +1 -0
  106. package/dist/translation-api.d.ts +288 -0
  107. package/dist/translation-api.d.ts.map +1 -0
  108. package/dist/types.d.ts +115 -0
  109. package/dist/types.d.ts.map +1 -0
  110. package/dist/utils.d.ts +115 -0
  111. package/dist/utils.d.ts.map +1 -0
  112. package/dist/utils_types.d.ts +14 -0
  113. package/drizzle/client/0000_bumpy_carnage.sql +33 -0
  114. package/drizzle/client/meta/0000_snapshot.json +199 -0
  115. package/drizzle/client/meta/_journal.json +13 -0
  116. package/drizzle/project/0000_spooky_lady_ursula.sql +192 -0
  117. package/drizzle/project/meta/0000_snapshot.json +1137 -0
  118. package/drizzle/project/meta/_journal.json +13 -0
  119. package/package.json +202 -0
  120. package/src/blob-api.js +139 -0
  121. package/src/blob-store/index.js +325 -0
  122. package/src/blob-store/live-download.js +373 -0
  123. package/src/config-import.js +604 -0
  124. package/src/constants.js +34 -0
  125. package/src/core-manager/bitfield-rle.js +235 -0
  126. package/src/core-manager/core-index.js +87 -0
  127. package/src/core-manager/index.js +504 -0
  128. package/src/core-manager/random-access-file-pool.js +30 -0
  129. package/src/core-manager/remote-bitfield.js +416 -0
  130. package/src/core-ownership.js +235 -0
  131. package/src/datastore/README.md +46 -0
  132. package/src/datastore/index.js +234 -0
  133. package/src/datatype/README.md +33 -0
  134. package/src/datatype/index.d.ts +108 -0
  135. package/src/datatype/index.js +358 -0
  136. package/src/discovery/local-discovery.js +303 -0
  137. package/src/errors.js +5 -0
  138. package/src/fastify-controller.js +84 -0
  139. package/src/fastify-plugins/blobs.js +139 -0
  140. package/src/fastify-plugins/constants.js +5 -0
  141. package/src/fastify-plugins/icons.js +158 -0
  142. package/src/fastify-plugins/maps/index.js +173 -0
  143. package/src/fastify-plugins/maps/offline-fallback-map.js +114 -0
  144. package/src/fastify-plugins/maps/static-maps.js +271 -0
  145. package/src/fastify-plugins/utils.js +52 -0
  146. package/src/generated/README.md +3 -0
  147. package/src/generated/extensions.d.ts +44 -0
  148. package/src/generated/extensions.js +196 -0
  149. package/src/generated/extensions.ts +237 -0
  150. package/src/generated/keys.d.ts +36 -0
  151. package/src/generated/keys.js +148 -0
  152. package/src/generated/keys.ts +185 -0
  153. package/src/generated/rpc.d.ts +87 -0
  154. package/src/generated/rpc.js +389 -0
  155. package/src/generated/rpc.ts +463 -0
  156. package/src/icon-api.js +282 -0
  157. package/src/index-writer/README.md +38 -0
  158. package/src/index-writer/index.js +124 -0
  159. package/src/index.js +16 -0
  160. package/src/invite-api.js +450 -0
  161. package/src/lib/hashmap.js +91 -0
  162. package/src/lib/hypercore-helpers.js +18 -0
  163. package/src/lib/noise-secret-stream-helpers.js +37 -0
  164. package/src/lib/ponyfills.js +25 -0
  165. package/src/lib/string.js +7 -0
  166. package/src/lib/timing-safe-equal.js +34 -0
  167. package/src/local-peers.js +737 -0
  168. package/src/logger.js +99 -0
  169. package/src/mapeo-manager.js +914 -0
  170. package/src/mapeo-project.js +980 -0
  171. package/src/member-api.js +319 -0
  172. package/src/roles.js +412 -0
  173. package/src/schema/client.js +55 -0
  174. package/src/schema/project.js +44 -0
  175. package/src/schema/schema-to-drizzle.js +118 -0
  176. package/src/schema/types.ts +153 -0
  177. package/src/schema/utils.js +51 -0
  178. package/src/sync/core-sync-state.js +440 -0
  179. package/src/sync/namespace-sync-state.js +193 -0
  180. package/src/sync/peer-sync-controller.js +332 -0
  181. package/src/sync/sync-api.js +588 -0
  182. package/src/sync/sync-state.js +63 -0
  183. package/src/translation-api.js +141 -0
  184. package/src/types.ts +149 -0
  185. package/src/utils.js +210 -0
  186. package/src/utils_types.d.ts +14 -0
@@ -0,0 +1,235 @@
1
+ // https://github.com/mafintosh/bitfield-rle/blob/31a0001/index.js
2
+ // Vendored so that we can run cross-platform tests with latest Node versions
3
+ // Modified to encode and decode Uint32Arrays
4
+
5
+ import varint from 'varint'
6
+
7
+ const isLittleEndian =
8
+ new Uint8Array(new Uint16Array([0xff]).buffer)[0] === 0xff
9
+ const isBigEndian = !isLittleEndian
10
+
11
+ // align to 4 bytes for Uint32Array output
12
+ const n = 4
13
+
14
+ class State {
15
+ /**
16
+ *
17
+ * @param {Buffer} input
18
+ * @param {Buffer | undefined} output
19
+ * @param {number} offset
20
+ */
21
+ constructor(input, output, offset) {
22
+ this.inputOffset = 0
23
+ this.inputLength = input.length
24
+ this.input = input
25
+ this.outputOffset = offset
26
+ this.output = output
27
+ }
28
+ }
29
+
30
+ encode.bytes = 0
31
+
32
+ /**
33
+ * @param {Uint32Array} bitfield
34
+ * @param {Buffer} [buffer]
35
+ * @param {number} [offset]
36
+ */
37
+ export function encode(bitfield, buffer, offset) {
38
+ if (!offset) offset = 0
39
+
40
+ const bitfieldBuf = Buffer.from(
41
+ bitfield.buffer,
42
+ bitfield.byteOffset,
43
+ bitfield.byteLength
44
+ )
45
+
46
+ // Encoded as little endian
47
+ if (isBigEndian) bitfieldBuf.swap32()
48
+
49
+ if (!buffer) buffer = Buffer.allocUnsafe(encodingLength(bitfieldBuf))
50
+ const state = new State(bitfieldBuf, buffer, offset)
51
+ rle(state)
52
+ encode.bytes = state.outputOffset - offset
53
+ return buffer
54
+ }
55
+
56
+ /**
57
+ * @param {Buffer} bitfield
58
+ */
59
+ function encodingLength(bitfield) {
60
+ const state = new State(bitfield, undefined, 0)
61
+ rle(state)
62
+ return state.outputOffset
63
+ }
64
+
65
+ decode.bytes = 0
66
+ /**
67
+ * @param {Buffer} buffer
68
+ * @param {number} [offset]
69
+ * @returns {Uint32Array}
70
+ */
71
+ export function decode(buffer, offset) {
72
+ if (!offset) offset = 0
73
+
74
+ const bitfieldBuf = Buffer.allocUnsafe(decodingLength(buffer, offset))
75
+ let ptr = 0
76
+
77
+ while (offset < buffer.length) {
78
+ const next = varint.decode(buffer, offset)
79
+ const repeat = next & 1
80
+ const len = repeat ? (next - (next & 3)) / 4 : next / 2
81
+
82
+ offset += varint.decode.bytes || 0
83
+
84
+ if (repeat) {
85
+ bitfieldBuf.fill(next & 2 ? 255 : 0, ptr, ptr + len)
86
+ } else {
87
+ buffer.copy(bitfieldBuf, ptr, offset, offset + len)
88
+ offset += len
89
+ }
90
+
91
+ ptr += len
92
+ }
93
+
94
+ bitfieldBuf.fill(0, ptr)
95
+ decode.bytes = buffer.length - offset
96
+
97
+ if (isBigEndian) bitfieldBuf.swap32()
98
+
99
+ return new Uint32Array(
100
+ bitfieldBuf.buffer,
101
+ bitfieldBuf.byteOffset,
102
+ bitfieldBuf.byteLength / n
103
+ )
104
+ }
105
+
106
+ /**
107
+ * @param {Buffer} buffer
108
+ * @param {number} offset
109
+ */
110
+ export function decodingLength(buffer, offset) {
111
+ if (!offset) offset = 0
112
+
113
+ let len = 0
114
+
115
+ while (offset < buffer.length) {
116
+ const next = varint.decode(buffer, offset)
117
+ offset += varint.decode.bytes || 0
118
+
119
+ const repeat = next & 1
120
+ const slice = repeat ? (next - (next & 3)) / 4 : next / 2
121
+
122
+ len += slice
123
+ if (!repeat) offset += slice
124
+ }
125
+
126
+ if (offset > buffer.length) throw new Error('Invalid RLE bitfield')
127
+
128
+ if (len & (n - 1)) return len + (n - (len & (n - 1)))
129
+
130
+ return len
131
+ }
132
+
133
+ /**
134
+ * @param {State} state
135
+ */
136
+ function rle(state) {
137
+ let len = 0
138
+ let bits = 0
139
+ const input = state.input
140
+
141
+ // Skip trimming for now, since it was breaking re-encoding to a Uint32Array.
142
+ // Only has a small memory overhead.
143
+
144
+ // while (state.inputLength > 0 && !input[state.inputLength - 1])
145
+ // state.inputLength--
146
+
147
+ for (let i = 0; i < state.inputLength; i++) {
148
+ if (input[i] === bits) {
149
+ len++
150
+ continue
151
+ }
152
+
153
+ if (len) encodeUpdate(state, i, len, bits)
154
+
155
+ if (input[i] === 0 || input[i] === 255) {
156
+ bits = input[i]
157
+ len = 1
158
+ } else {
159
+ len = 0
160
+ }
161
+ }
162
+
163
+ if (len) encodeUpdate(state, state.inputLength, len, bits)
164
+ encodeFinal(state)
165
+ }
166
+
167
+ /**
168
+ * @param {State & { output: Buffer }} state
169
+ * @param {number} end
170
+ */
171
+ function encodeHead(state, end) {
172
+ const headLength = end - state.inputOffset
173
+ varint.encode(2 * headLength, state.output, state.outputOffset)
174
+ state.outputOffset += varint.encode.bytes || 0
175
+ state.input.copy(state.output, state.outputOffset, state.inputOffset, end)
176
+ state.outputOffset += headLength
177
+ }
178
+
179
+ /**
180
+ * @param {State} state
181
+ */
182
+ function encodeFinal(state) {
183
+ const headLength = state.inputLength - state.inputOffset
184
+ if (!headLength) return
185
+
186
+ if (!stateHasOutput(state)) {
187
+ state.outputOffset += headLength + varint.encodingLength(2 * headLength)
188
+ } else {
189
+ encodeHead(state, state.inputLength)
190
+ }
191
+
192
+ state.inputOffset = state.inputLength
193
+ }
194
+
195
+ /**
196
+ *
197
+ * @param {State} state
198
+ * @param {number} i
199
+ * @param {number} len
200
+ * @param {number} bit
201
+ * @returns {void}
202
+ */
203
+ function encodeUpdate(state, i, len, bit) {
204
+ const headLength = i - len - state.inputOffset
205
+ const headCost = headLength
206
+ ? varint.encodingLength(2 * headLength) + headLength
207
+ : 0
208
+ const enc = 4 * len + (bit ? 2 : 0) + 1 // len << 2 | bit << 1 | 1
209
+ const encCost = headCost + varint.encodingLength(enc)
210
+ const baseCost =
211
+ varint.encodingLength(2 * (i - state.inputOffset)) + i - state.inputOffset
212
+
213
+ if (encCost >= baseCost) return
214
+
215
+ if (!stateHasOutput(state)) {
216
+ state.outputOffset += encCost
217
+ state.inputOffset = i
218
+ return
219
+ }
220
+
221
+ if (headLength) encodeHead(state, i - len)
222
+
223
+ varint.encode(enc, state.output, state.outputOffset)
224
+ state.outputOffset += varint.encode.bytes || 0
225
+ state.inputOffset = i
226
+ }
227
+
228
+ /**
229
+ *
230
+ * @param {State} state
231
+ * @returns {state is State & { output: Buffer }}
232
+ */
233
+ function stateHasOutput(state) {
234
+ return !!state.output
235
+ }
@@ -0,0 +1,87 @@
1
+ import crypto from 'hypercore-crypto'
2
+ /** @import { Namespace } from '../types.js' */
3
+ /** @import { CoreRecord } from './index.js' */
4
+
5
+ /**
6
+ * An in-memory index of open cores.
7
+ */
8
+ export class CoreIndex {
9
+ /** @type {Map<string, CoreRecord>} */
10
+ #coresByDiscoveryId = new Map()
11
+ /** @type {Map<Namespace, CoreRecord>} */
12
+ #writersByNamespace = new Map();
13
+
14
+ [Symbol.iterator]() {
15
+ return this.#coresByDiscoveryId.values()
16
+ }
17
+
18
+ /**
19
+ * NB. Need to pass key here because `core.key` is not populated until the
20
+ * core is ready, but we know it beforehand.
21
+ *
22
+ * @param {Object} options
23
+ * @param {import('hypercore')<"binary", Buffer>} options.core Hypercore instance
24
+ * @param {Buffer} options.key Buffer containing public key of this core
25
+ * @param {Namespace} options.namespace
26
+ * @param {boolean} [options.writer] Is this a writer core?
27
+ */
28
+ add({ core, key, namespace, writer = false }) {
29
+ const discoveryKey = crypto.discoveryKey(key)
30
+ const discoveryId = discoveryKey.toString('hex')
31
+ const record = { core, key, namespace }
32
+ if (writer) {
33
+ this.#writersByNamespace.set(namespace, record)
34
+ }
35
+ this.#coresByDiscoveryId.set(discoveryId, record)
36
+ }
37
+
38
+ /**
39
+ * Get all known cores in a namespace
40
+ *
41
+ * @param {Namespace} namespace
42
+ * @returns {CoreRecord[]}
43
+ */
44
+ getByNamespace(namespace) {
45
+ const records = []
46
+ for (const record of this.#coresByDiscoveryId.values()) {
47
+ if (record.namespace === namespace) records.push(record)
48
+ }
49
+ return records
50
+ }
51
+
52
+ /**
53
+ * Get the write core for the given namespace
54
+ *
55
+ * @param {Namespace} namespace
56
+ * @returns {CoreRecord}
57
+ */
58
+ getWriter(namespace) {
59
+ const writerRecord = this.#writersByNamespace.get(namespace)
60
+ // Shouldn't happen, since we add all the writers in the contructor
61
+ if (!writerRecord) {
62
+ throw new Error(`Writer for namespace '${namespace}' is not defined`)
63
+ }
64
+ return writerRecord
65
+ }
66
+
67
+ /**
68
+ * Get a core by its discoveryId (discover key as hex string)
69
+ *
70
+ * @param {string} discoveryId
71
+ * @returns {CoreRecord | undefined}
72
+ */
73
+ getByDiscoveryId(discoveryId) {
74
+ return this.#coresByDiscoveryId.get(discoveryId)
75
+ }
76
+
77
+ /**
78
+ * Get a core by its public key
79
+ *
80
+ * @param {Buffer} coreKey
81
+ * @returns {CoreRecord | undefined}
82
+ */
83
+ getByCoreKey(coreKey) {
84
+ const discoveryId = crypto.discoveryKey(coreKey).toString('hex')
85
+ return this.#coresByDiscoveryId.get(discoveryId)
86
+ }
87
+ }