Skip to content

Commit

Permalink
feat: node and storage
Browse files Browse the repository at this point in the history
  • Loading branch information
streamich committed Sep 10, 2017
1 parent 3d5c31a commit 0ff94ad
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 45 deletions.
14 changes: 14 additions & 0 deletions demo/localstorage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import {createVolume} from '../src/volume-localstorage';

const obj = {};
const Volume = createVolume('default', obj);

const vol = new Volume;
vol.fromJSON({'/foo': 'bar', '/foo2': 'bar2'});
// vol.unlinkSync('/foo');

console.log(obj);
console.log(vol.toJSON());



11 changes: 11 additions & 0 deletions src/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,17 @@ export class Link extends EventEmitter {
if(!link) return null;
return link.walk(steps, stop, i + 1);
}

toJSON() {
for(let ch in this.children) {
console.log('ch', ch);
}
return {
steps: this.steps,
ino: this.ino,
children: Object.keys(this.children),
};
}
}


Expand Down
87 changes: 52 additions & 35 deletions src/volume-localstorage.ts
Original file line number Diff line number Diff line change
@@ -1,53 +1,52 @@
import {Volume} from "./volume";
import {Link, Node} from "./node";

const LS = {};

export class NodeLocalstorage extends Node {
key() {
return `memfs.ino.${this.ino}`;
}
export interface IStore {
setItem(key: string, json);
getItem(key: string);
removeItem(key: string);
}

sync() {
LS[this.key()] = this.toJSON();
}

touch() {
super.touch();
this.sync();
}
export class ObjectStore {

del() {
delete LS[this.key()];
}
}

export class LinkLocalstorage extends Link {
obj: object;

}
constructor(obj) {
this.obj = obj;
}

export class VolumeLocalstorage extends Volume {
constructor() {
super({
Node: NodeLocalstorage,
Link: LinkLocalstorage,
});
setItem(key: string, json) {
this.obj[key] = JSON.stringify(json);
}

getItem(key: string) {
const data = this.obj[key];
if(typeof data === void 0) return void 0;
return JSON.parse(data);
}

removeItem(key: string) {
delete this.obj[key];
}
}

export function createVolume(namespace: string, LS = localStorage) {

export function createVolume(namespace: string, LS: Storage | object = localStorage): new (...args) => Volume {
const store = new ObjectStore(LS);
const key = (type, id) => `memfs.${namespace}.${type}.${id}`;

export class NodeLocalstorage extends Node {
key() {
return key('ino', this.ino);
class NodeLocalStorage extends Node {
private _key: string;

get Key(): string {
if(!this._key) this._key = key('ino', this.ino);
return this._key;
}

sync() {
LS[this.key()] = this.toJSON();
store.setItem(this.Key, this.toJSON());
}

touch() {
Expand All @@ -57,22 +56,40 @@ export function createVolume(namespace: string, LS = localStorage) {

del() {
super.del();
delete LS[this.key()];
store.removeItem(this.Key);
}
}

export class LinkLocalstorage extends Link {
class LinkLocalStorage extends Link {
private _key: string;

get Key(): string {
if(!this._key) this._key = key('link', this.getPath());
return this._key;
}

sync() {
store.setItem(this,Key, this.toJSON()):
}
}

export class VolumeLocalstorage extends Volume {
return class VolumeLocalStorage extends Volume {
constructor() {
super({
Node: NodeLocalstorage,
Link: LinkLocalstorage,
Node: NodeLocalStorage,
Link: LinkLocalStorage,
});
}

createLink(parent?, name?, isDirectory?, perm?) {
const link = super.createLink(parent, name, isDirectory, perm);
store.setItem(key('link', link.getPath()), link.toJSON());
return link;
}

deleteLink(link) {
store.removeItem(key('link', link.getPath()));
return super.deleteLink(link);
}
}
}
11 changes: 11 additions & 0 deletions src/volume.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,17 @@ describe('volume', () => {
expect(link1).to.equal(node2);
});
});
describe('i-nodes', () => {
it('i-node numbers are unique', () => {
const vol = Volume.fromJSON({
'/1': 'foo',
'/2': 'bar',
});
const stat1 = vol.statSync('/1');
const stat2 = vol.statSync('/2');
expect(stat1.ino === stat2.ino).to.be.false;
});
});
describe('.toJSON()', () => {
it('Single file', () => {
const vol = new Volume;
Expand Down
26 changes: 16 additions & 10 deletions src/volume.ts
Original file line number Diff line number Diff line change
Expand Up @@ -507,9 +507,6 @@ export class Volume {
return vol;
}

// I-node number counter.
static ino: number = 0;

/**
* Global file descriptor counter. UNIX file descriptors start from 0 and go sequentially
* up, so here, in order not to conflict with them, we choose some big number and descrease
Expand All @@ -526,6 +523,10 @@ export class Volume {
// root: Node = new (this.NodeClass)(null, '', true);
root: Link;


// I-node number counter.
ino: number = 0;

// A mapping for i-node numbers to i-nodes (`Node`);
inodes: {[ino: number]: Node} = {};

Expand Down Expand Up @@ -557,9 +558,9 @@ export class Volume {
};

constructor(props = {}) {
this.props = extend(props, {Node, Link, File});
this.props = extend({Node, Link, File}, props);

const root = new this.props.Link(this, null, '');
const root = this.createLink();
root.setNode(this.createNode(true));

const self = this;
Expand Down Expand Up @@ -599,8 +600,12 @@ export class Volume {
this.root = root;
}

createLink(parent: Link, name: string, isDirectory: boolean = false, perm?: number): Link {
return parent.createChild(name, this.createNode(isDirectory, perm));
createLink(): Link;
createLink(parent: Link, name: string, isDirectory?: boolean, perm?: number): Link;
createLink(parent?: Link, name?: string, isDirectory: boolean = false, perm?: number): Link {
return parent
? parent.createChild(name, this.createNode(isDirectory, perm))
: new this.props.Link(this, null, '');
}

deleteLink(link: Link): boolean {
Expand All @@ -617,8 +622,8 @@ export class Volume {
private newInoNumber(): number {
if(this.releasedInos.length) return this.releasedInos.pop();
else {
Volume.ino = (Volume.ino++) % 0xFFFFFFFF;
return Volume.ino;
this.ino = (this.ino + 1) % 0xFFFFFFFF;
return this.ino;
}
}

Expand Down Expand Up @@ -825,13 +830,14 @@ export class Volume {
}

reset() {
this.ino = 0;
this.inodes = {};
this.releasedInos = [];
this.fds = {};
this.releasedFds = [];
this.openFiles = 0;

this.root = new this.props.Link(this, null, '');
this.root = this.createLink();
this.root.setNode(this.createNode(true));
}

Expand Down

0 comments on commit 0ff94ad

Please sign in to comment.