Skip to content

Commit

Permalink
feat: 🎸 add ability to write at offset and append in FSA CRUD
Browse files Browse the repository at this point in the history
  • Loading branch information
streamich committed Jul 27, 2024
1 parent dead41c commit 47d0c93
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 2 deletions.
38 changes: 38 additions & 0 deletions src/crud/__tests__/testCrudfs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,44 @@ export const testCrudfs = (setup: Setup) => {
'/a/b/bar': '3',
});
});

test('overwrites existing data', async () => {
const { crud, snapshot } = setup();
await crud.put(['a', 'b'], 'bar', b('abc'));
await crud.put(['a', 'b'], 'bar', b('.'));
expect(snapshot()).toStrictEqual({
'/a/b/bar': '.',
});
});

test('can write at offset', async () => {
const { crud, snapshot } = setup();
await crud.put(['a', 'b'], 'bar', b('abc'));
await crud.put(['a', 'b'], 'bar', b('.'), {pos: 1});
expect(snapshot()).toStrictEqual({
'/a/b/bar': 'a.c',
});
});

test('can write at the beginning of file', async () => {
const { crud, snapshot } = setup();
await crud.put(['a', 'b'], 'bar', b('abc'));
await crud.put(['a', 'b'], 'bar', b('.'), {pos: 0});
expect(snapshot()).toStrictEqual({
'/a/b/bar': '.bc',
});
});

test('can append to the file', async () => {
const { crud, snapshot } = setup();
await crud.put(['a', 'b'], 'bar', b('abc'));
await crud.put(['a', 'b'], 'bar', b('1'), {pos: -1});
await crud.put(['a', 'b'], 'bar', b('2'), {pos: -1});
await crud.put(['a', 'b'], 'bar', b('3'), {pos: -1});
expect(snapshot()).toStrictEqual({
'/a/b/bar': 'abc123',
});
});
});

describe('.get()', () => {
Expand Down
11 changes: 11 additions & 0 deletions src/crud/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,18 @@ export interface CrudApi {
export type CrudCollection = string[];

export interface CrudPutOptions {
/**
* Specifies conditions for throwing an error.
*/
throwIf?: 'exists' | 'missing';

/**
* Specifies the position where to write the data. If not set, or set to
* `undefined` the existing resource is discarded and the new data replaces
* it. If set, the new data will be inserted at the specified position. If
* set, to `-1` the new data will be appended to the existing resource.
*/
pos?: undefined | number | -1;
}

export interface CrudCollectionEntry {
Expand Down
21 changes: 19 additions & 2 deletions src/fsa-to-crud/FsaCrud.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,25 @@ export class FsaCrud implements crud.CrudApi {
file = await dir.getFileHandle(id, { create: true });
}
}
const writable = await file!.createWritable();
await writable.write(data);
let pos = options?.pos;
const writable = await file!.createWritable({keepExistingData: typeof pos !== 'undefined'});
switch (typeof pos) {
case 'undefined': {
await writable.write(data);
break;
}
case 'number': {
if (pos === -1) {
const blob = await file.getFile();
pos = blob.size;
}
await writable.write({type: 'write', data, position: pos});
break;
}
default: {
throw new Error(`Invalid position: ${pos}`);
}
}
await writable.close();
};

Expand Down

0 comments on commit 47d0c93

Please sign in to comment.