<commit_before>// Returns fragment generator, where each returned fragment emits selected data for specified object

'use strict';

var aFrom           = require('es5-ext/array/from')
  , ensureString    = require('es5-ext/object/validate-stringifiable-value')
  , ensureSet       = require('es6-set/valid-set')
  , deferred        = require('deferred')
  , memoize         = require('memoizee/plain')
  , Fragment        = require('data-fragment')
  , ensureStorage   = require('dbjs-persistence/ensure-storage')
  , assimilateEvent = require('./lib/assimilate-driver-event')
  , anyIdToStorage  = require('../utils/any-id-to-storage');

module.exports = function (storage, keyPaths) {
	var keyPathsArray, storagePromise;
	if (storage != null) storagePromise = deferred(ensureStorage(storage));

	ensureSet(keyPaths);

	keyPathsArray = aFrom(keyPaths);

	return memoize(function (ownerId) {
		var fragment, promise;
		ownerId = ensureString(ownerId);
		fragment = new Fragment();
		if (storage) promise = storagePromise;
		else promise = anyIdToStorage(ownerId);
		fragment.promise = promise(function (storage) {
			storage.on('owner:' + ownerId, function (event) {
				if (event.type === 'reduced') return;
				if (!event.keyPath || keyPaths.has(event.keyPath)) {
					if (event.type === 'direct') fragment.update(event.id, event.data);
					else assimilateEvent(fragment, event.id, event.data);
				}
			});
			return deferred(
				storage.get(ownerId)(function (data) {
					if (data) fragment.update(ownerId, data);
				}),
				storage.getObject(ownerId, { keyPaths: keyPaths })(function (data) {
					data.forEach(function (data) { fragment.update(data.id, data.data); });
				}),
				deferred.map(keyPathsArray, function (keyPath) {
					var id = ownerId + '/' + keyPath;
					return storage.getComputed(id)(function (data) {
						if (!data) return;
						assimilateEvent(fragment, id, data);
					});
				})
			);
		});
		return fragment;
	});
};<commit_msg>Support per multiple item access<commit_after>// Returns fragment generator, where each returned fragment emits selected data for specified object

'use strict';

var aFrom           = require('es5-ext/array/from')
  , ensureString    = require('es5-ext/object/validate-stringifiable-value')
  , ensureSet       = require('es6-set/valid-set')
  , deferred        = require('deferred')
  , memoize         = require('memoizee/plain')
  , Fragment        = require('data-fragment')
  , resolveKeyPath  = require('dbjs/_setup/utils/resolve-key-path')
  , ensureStorage   = require('dbjs-persistence/ensure-storage')
  , assimilateEvent = require('./lib/assimilate-driver-event')
  , anyIdToStorage  = require('../utils/any-id-to-storage');

module.exports = function (storage, keyPaths) {
	var keyPathsArray, storagePromise;
	if (storage != null) storagePromise = deferred(ensureStorage(storage));

	ensureSet(keyPaths);

	keyPathsArray = aFrom(keyPaths);

	return memoize(function (ownerId) {
		var fragment, promise;
		ownerId = ensureString(ownerId);
		fragment = new Fragment();
		if (storage) promise = storagePromise;
		else promise = anyIdToStorage(ownerId);
		fragment.promise = promise(function (storage) {
			storage.on('owner:' + ownerId, function (event) {
				if (event.type === 'reduced') return;
				if (!event.keyPath || keyPaths.has(event.path) || keyPaths.has(event.keyPath)) {
					if (event.type === 'direct') fragment.update(event.id, event.data);
					else assimilateEvent(fragment, event.id, event.data);
				}
			});
			return deferred(
				storage.getObject(ownerId)(function (data) {
					data.forEach(function (data) {
						var path = (data.id === ownerId) ? null : data.id.slice(data.id.indexOf('/') + 1)
						  , keyPath = path ? resolveKeyPath(data.id) : null;
						if (path && !keyPaths.has(path) && !keyPaths.has(keyPath)) return;
						fragment.update(data.id, data.data);
					});
				}),
				deferred.map(keyPathsArray, function (keyPath) {
					var id = ownerId + '/' + keyPath;
					return storage.getComputed(id)(function (data) {
						if (!data) return;
						assimilateEvent(fragment, id, data);
					});
				})
			);
		});
		return fragment;
	});
};
{'fraction_non_alphanumeric': 0.15007215007215008, 'fraction_numerical': 0.0016835016835016834, 'mean_word_length': 3.646927374301676, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3308321', 'n_tokens_mistral': 1473, 'n_tokens_neox': 1274, 'n_words': 266}