nappup 1.5.8 → 1.5.9

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 (2) hide show
  1. package/package.json +1 -1
  2. package/src/index.js +36 -4
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "url": "git+https://github.com/44billion/nappup.git"
7
7
  },
8
8
  "license": "MIT",
9
- "version": "1.5.8",
9
+ "version": "1.5.9",
10
10
  "description": "Nostr App Uploader",
11
11
  "type": "module",
12
12
  "scripts": {
package/src/index.js CHANGED
@@ -166,14 +166,46 @@ export async function toApp (fileList, nostrSigner, { log = () => {}, dTag, dTag
166
166
  }
167
167
 
168
168
  async function uploadBinaryDataChunks ({ nmmr, signer, filename, chunkLength, log, pause = 0, mimeType, shouldReupload = false }) {
169
+ const pubkey = await signer.getPublicKey()
169
170
  const writeRelays = (await signer.getRelays()).write
170
171
  const relays = [...new Set([...writeRelays, ...nappRelays].map(r => r.trim().replace(/\/$/, '')))]
172
+
173
+ // Find max stored created_at for this file's chunks
174
+ const rootHash = nmmr.getRoot()
175
+ const allCTags = Array.from({ length: chunkLength }, (_, i) => `${rootHash}:${i}`)
176
+ let maxStoredCreatedAt = 0
177
+
178
+ for (let i = 0; i < allCTags.length; i += 100) {
179
+ const batch = allCTags.slice(i, i + 100)
180
+ const storedEvents = (await nostrRelays.getEvents({
181
+ kinds: [34600],
182
+ authors: [pubkey],
183
+ '#c': batch,
184
+ limit: 1
185
+ }, relays)).result
186
+
187
+ if (storedEvents.length > 0) {
188
+ // Since results are desc sorted by created_at, the first one is the max
189
+ maxStoredCreatedAt = Math.max(maxStoredCreatedAt, storedEvents[0].created_at)
190
+ }
191
+ }
192
+
193
+ // Set initial created_at based on what's higher, maxStoredCreatedAt or current time
194
+ let createdAtCursor = (Math.max(maxStoredCreatedAt, Math.floor(Date.now() / 1000)) + chunkLength)
195
+
171
196
  let chunkIndex = 0
172
197
  for await (const chunk of nmmr.getChunks()) {
173
198
  const dTag = chunk.x
174
199
  const currentCtag = `${chunk.rootX}:${chunk.index}`
175
200
  const { otherCtags, hasCurrentCtag, foundEvent, missingRelays } = await getPreviousCtags(dTag, currentCtag, relays, signer)
176
201
  if (!shouldReupload && hasCurrentCtag) {
202
+ // Handling of partial uploads/resumes:
203
+ // If we are observing an existing chunk, we use its created_at to re-align our cursor
204
+ // for the next chunks (so next chunk will be this_chunk_time - 1)
205
+ if (foundEvent) {
206
+ createdAtCursor = foundEvent.created_at - 1
207
+ }
208
+
177
209
  if (missingRelays.length === 0) {
178
210
  log(`${filename}: Skipping chunk ${++chunkIndex} of ${chunkLength} (already uploaded)`)
179
211
  continue
@@ -183,10 +215,10 @@ async function uploadBinaryDataChunks ({ nmmr, signer, filename, chunkLength, lo
183
215
  continue
184
216
  }
185
217
 
186
- const createdAt = Math.floor(Date.now() / 1000)
187
- let effectiveCreatedAt = (foundEvent && foundEvent.created_at >= createdAt) ? foundEvent.created_at + 1 : createdAt
188
- const maxCreatedAt = createdAt + 172800 // 2 days ahead
189
- if (effectiveCreatedAt > maxCreatedAt) effectiveCreatedAt = maxCreatedAt
218
+ const effectiveCreatedAt = createdAtCursor
219
+ // The lower chunk index, the higher created_at must be
220
+ // for relays to serve chunks in the most efficient order
221
+ createdAtCursor--
190
222
 
191
223
  const binaryDataChunk = {
192
224
  kind: 34600,