braid-text 0.2.109 → 0.2.111

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/index.js +90 -3
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -9,7 +9,10 @@ function create_braid_text() {
9
9
  db_folder: './braid-text-db',
10
10
  length_cache_size: 10,
11
11
  meta_file_save_period_ms: 1000,
12
- cache: {}
12
+ cache: {},
13
+ backups: false,
14
+ backups_folder: './braid-text-backups',
15
+ backups_interval: 60 * 1000
13
16
  }
14
17
 
15
18
  let waiting_puts = 0
@@ -305,11 +308,13 @@ function create_braid_text() {
305
308
  var cv = remote_res.headers.get('current-version')
306
309
  await braid_text.put(a, {
307
310
  body: update.body,
308
- transfer_encoding: 'dt'
311
+ transfer_encoding: 'dt',
312
+ peer: options.peer
309
313
  })
310
314
  if (signal.aborted) return
311
315
  if (cv) extend_fork_point({ version: JSON.parse(`[${cv}]`), parents: resource.meta.fork_point || [] })
312
316
  } else {
317
+ if (options.peer) update.peer = options.peer
313
318
  await braid_text.put(a, update)
314
319
  if (signal.aborted) return
315
320
  if (update.version) extend_fork_point(update)
@@ -880,7 +885,9 @@ function create_braid_text() {
880
885
 
881
886
  // Notify non-simpleton clients with the dt-encoded update
882
887
  var dt_update = { body, encoding: 'dt' }
883
- await Promise.all([...resource.clients].map(client => client.my_subscribe(dt_update)))
888
+ await Promise.all([...resource.clients].
889
+ filter(client => !peer || client.peer !== peer).
890
+ map(client => client.my_subscribe(dt_update)))
884
891
 
885
892
  return { change_count: end_i - start_i + 1 }
886
893
  }
@@ -1295,10 +1302,89 @@ function create_braid_text() {
1295
1302
  var files = (await fs.promises.readdir(braid_text.db_folder))
1296
1303
  .filter(x => /\.\d+$/.test(x))
1297
1304
  init_filename_mapping(files)
1305
+
1306
+ // Start backups if enabled
1307
+ if (braid_text.backups) backup_init()
1298
1308
  })()
1299
1309
  await db_folder_init.p
1300
1310
  }
1301
1311
 
1312
+ function backup_init() {
1313
+ if (backup_init.started) return
1314
+ backup_init.started = true
1315
+
1316
+ setInterval(async function backup_braid_text_db() {
1317
+ var path = require('path')
1318
+ var src_dir = braid_text.db_folder
1319
+ var backup_dir = braid_text.backups_folder
1320
+
1321
+ // Create backup dir if it doesn't exist
1322
+ await fs.promises.mkdir(backup_dir, { recursive: true })
1323
+
1324
+ // Get current date string
1325
+ var d = new Date()
1326
+ var y = d.getYear() + 1900
1327
+ var m = d.getMonth() + 1
1328
+ if (m < 10) m = '0' + m
1329
+ var day = d.getDate()
1330
+ if (day < 10) day = '0' + day
1331
+ var date = y + '-' + m + '-' + day
1332
+
1333
+ // Read files in src_dir (non-recursive)
1334
+ var files
1335
+ try {
1336
+ files = await fs.promises.readdir(src_dir)
1337
+ } catch (e) { return }
1338
+
1339
+ for (var file of files) {
1340
+ // Only process files ending with .N where N is an integer
1341
+ var match = file.match(/^(.+)\.(\d+)$/)
1342
+ if (!match) continue
1343
+
1344
+ var base_name = match[1]
1345
+ var src_path = path.join(src_dir, file)
1346
+
1347
+ // Get source file stats
1348
+ var src_stat
1349
+ try {
1350
+ src_stat = await fs.promises.stat(src_path)
1351
+ } catch (e) { continue }
1352
+
1353
+ // Skip directories
1354
+ if (!src_stat.isFile()) continue
1355
+
1356
+ // Create backup subdir for this base_name if needed
1357
+ var file_backup_dir = path.join(backup_dir, base_name)
1358
+ await fs.promises.mkdir(file_backup_dir, { recursive: true })
1359
+
1360
+ // Check if we need to backup (compare mtime with most recent backup)
1361
+ var backup_path = path.join(file_backup_dir, date)
1362
+ var needs_backup = true
1363
+
1364
+ try {
1365
+ // Find the latest backup file (sorted by date name)
1366
+ var backups = await fs.promises.readdir(file_backup_dir)
1367
+ if (backups.length > 0) {
1368
+ backups.sort()
1369
+ var latest_backup = backups[backups.length - 1]
1370
+ var latest_backup_path = path.join(file_backup_dir, latest_backup)
1371
+ var backup_stat = await fs.promises.stat(latest_backup_path)
1372
+ // Only backup if source is newer than latest backup
1373
+ if (src_stat.mtimeMs <= backup_stat.mtimeMs)
1374
+ needs_backup = false
1375
+ }
1376
+ } catch (e) {
1377
+ // Backup dir empty or doesn't exist, so we need to create backup
1378
+ }
1379
+
1380
+ if (needs_backup) {
1381
+ require('child_process').execFile(
1382
+ '/bin/cp', [src_path, backup_path])
1383
+ }
1384
+ }
1385
+ }, braid_text.backups_interval)
1386
+ }
1387
+
1302
1388
  async function get_files_for_key(key) {
1303
1389
  await db_folder_init()
1304
1390
  try {
@@ -2848,6 +2934,7 @@ function create_braid_text() {
2848
2934
  braid_text.get_resource = get_resource
2849
2935
 
2850
2936
  braid_text.db_folder_init = db_folder_init
2937
+ braid_text.backup_init = backup_init
2851
2938
  braid_text.encode_filename = encode_filename
2852
2939
  braid_text.decode_filename = decode_filename
2853
2940
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "braid-text",
3
- "version": "0.2.109",
3
+ "version": "0.2.111",
4
4
  "description": "Library for collaborative text over http using braid.",
5
5
  "author": "Braid Working Group",
6
6
  "repository": "braid-org/braid-text",