-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
392 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import BaseEntity from '../models/BaseEntity' | ||
import getSlothData from '../utils/getSlothData' | ||
import { join } from 'path' | ||
import getProtoData from '../utils/getProtoData' | ||
import SlothView from './SlothView' | ||
|
||
/** | ||
* Creates an index for a field. It's a view function that simply emits | ||
* the document key | ||
* | ||
* @see [[SlothDatabase.queryDocs]] | ||
* @export | ||
* @template S | ||
* @param {(doc: S, emit: Function) => void} fn the view function, as arrow or es5 function | ||
* @param {string} [docId='views'] the _design document identifier | ||
* @param {string} [viewId] the view identifier, default by_<property name> | ||
* @returns the decorator to apply on the field | ||
*/ | ||
export default function SlothIndex<S, V extends string = string>( | ||
viewId?: V, | ||
docId?: string | ||
) { | ||
return (target: object, key: string) => { | ||
SlothView( | ||
new Function('doc', 'emit', `emit(doc['${key}'].toString());`) as any, | ||
viewId, | ||
docId | ||
)(target, key) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import BaseEntity from '../models/BaseEntity' | ||
import getSlothData from '../utils/getSlothData' | ||
import { join } from 'path' | ||
import getProtoData from '../utils/getProtoData' | ||
|
||
/** | ||
* Creates a view for a field. This function does not modify the | ||
* behavior of the current field, hence requires another decorator | ||
* such as SlothURI or SlothField. The view will be created by the SlothDatabase | ||
* | ||
* @export | ||
* @template S | ||
* @param {(doc: S, emit: Function) => void} fn the view function, as arrow or es5 function | ||
* @param {string} [docId='views'] the _design document identifier | ||
* @param {string} [viewId] the view identifier, default by_<property name> | ||
* @returns the decorator to apply on the field | ||
*/ | ||
export default function SlothView<S, V extends string = string>( | ||
fn: (doc: S, emit: Function) => void, | ||
viewId?: V, | ||
docId = 'views' | ||
) { | ||
return (target: object, key: string) => { | ||
const desc = Reflect.getOwnPropertyDescriptor(target, key) | ||
|
||
if (desc) { | ||
if (!desc.get && !desc.set) { | ||
throw new Error('Required SlothView on top of another decorator') | ||
} | ||
} | ||
|
||
const fun = `function (__doc) { | ||
(${fn.toString()})(__doc, emit); | ||
}` | ||
|
||
const { views } = getProtoData(target, true) | ||
|
||
views.push({ | ||
id: docId, | ||
name: viewId || `by_${key}`, | ||
function: fn, | ||
code: fun | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import Artist from './Artist' | ||
import Track, { TrackViews } from './Track' | ||
import PouchDB from 'pouchdb' | ||
import delay from '../utils/delay' | ||
|
||
PouchDB.plugin(require('pouchdb-adapter-memory')) | ||
|
||
describe('views', () => { | ||
const prefix = Date.now().toString(26) + '_' | ||
|
||
const factory = (name: string) => | ||
new PouchDB(prefix + name, { adapter: 'memory' }) | ||
|
||
beforeAll(async () => { | ||
await Track.put(factory, { | ||
name: 'Palm Trees', | ||
artist: 'library/flatbush-zombies', | ||
album: 'library/flatbush-zombies/betteroffdead', | ||
number: '12' | ||
}) | ||
await Track.put(factory, { | ||
name: 'Not Palm Trees', | ||
artist: 'library/not-flatbush-zombies', | ||
album: 'library/flatbush-zombies/betteroffdead-2', | ||
number: '12' | ||
}) | ||
await Track.put(factory, { | ||
name: 'Mocking Bird', | ||
artist: 'library/eminem', | ||
album: 'library/eminem/some-album-i-forgot', | ||
number: '12' | ||
}) | ||
}) | ||
|
||
test('create views', async () => { | ||
await Track.initSetup(factory) | ||
expect(await factory('tracks').get('_design/views')).toMatchObject({ | ||
views: { by_album: {} } | ||
}) | ||
}) | ||
|
||
test('query by view', async () => { | ||
const docs = await Track.queryDocs( | ||
factory, | ||
TrackViews.ByAlbum, | ||
'library/flatbush-zombies' | ||
) | ||
|
||
expect(docs.length).toBe(2) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { SlothView } from '../../../src/slothdb' | ||
import emptyProtoData from '../../utils/emptyProtoData' | ||
|
||
test('SlothView - fails without a decorator', () => { | ||
const obj = { foo: 'bar' } | ||
expect(() => SlothView(() => ({}))(obj, 'foo')).toThrowError( | ||
/Required SlothView/ | ||
) | ||
}) | ||
|
||
test('SlothView - generates a working function for es5 view', () => { | ||
const proto = emptyProtoData({}) | ||
const obj = { __protoData: proto } | ||
|
||
Reflect.defineProperty(obj, 'foo', { get: () => 42 }) | ||
|
||
SlothView(function(doc: { bar: string }, emit) { | ||
emit(doc.bar) | ||
})(obj, 'foo') | ||
|
||
expect(proto.views).toHaveLength(1) | ||
|
||
const { views } = proto | ||
const [{ id, name, code }] = views | ||
|
||
expect(name).toBe('by_foo') | ||
|
||
let fun: Function | ||
|
||
const emit = jest.fn() | ||
|
||
// tslint:disable-next-line:no-eval | ||
eval('fun = ' + code) | ||
fun({ bar: 'barz' }) | ||
|
||
expect(emit).toHaveBeenCalledWith('barz') | ||
}) |
Oops, something went wrong.