Home Reference Source Repository

src/TransientsProperty.js

import {
	assert,
	doneIterator,
	iteratorFor,
	iterateOver,
} from "akutils";

import ObjectProperty from "./ObjectProperty";
import Shadow from "./Shadow";
import StateType from "./StateType";
import TransientProperty from "./TransientProperty";

import appDebug, { TransientKey as DebugKey } from "./debug";
const debug = appDebug(DebugKey);


/**
	The shadow api for the {@link Store#transients} property. This api implements a superset of the
	[Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) class.
*/
export class TransientsShadow extends Shadow {
	/*
		Gets the number of transient objects.
	*/
	get size() {
		return this.__().size();
	}

	/**
		Removes all transient objects.
	*/
	clear() {
		this.__().clear();
	}

	/**
		Removes the speecified transient object from {@link Store#transients}.

		@param id - the transient key
	*/
	delete(id) {
		this.$$()._keyed.removeProperty(id);
	}

	/**
		Gets an [Iterator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators)
		object that contains the `[id, {@link TransientShadow}]` pairs for each transient property in the
		{@link Store#transients} property.
	*/
	entries() {
		return iterateOver(this.__().keys(), key => [ key, this[key] ] );
	}

	/**
		Gets if the {@link Store#transients} object contains a transient object.
	*/
	has(id) {
		return this.__().has(id);
	}

	/**
		Gets an [Iterator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators)
		object that contains the transient keys.
	*/
	keys() {
		return iteratorFor(this.__().keys());
	}

	/**
		Adds or updates a {@link TransientProperty} with a specified id. The returned {@link TransientProperty#link}
		method must be called immediately following this method invocation or the property may be swept from the
		transient list after the next store update.

		@param id - the transient key
		@param {Property} property - a `Property` instance to track in the transients property.

		@return the {@link TransientProperty} containing the `property` instance passed into the
			method.
	*/
	set(id, property) {
		assert( a => a.is(id, "id must be specifeid for setting a transient property") );

		var trans = new TransientProperty(id, property);

		this.$$()._keyed.addProperty(id, trans);

		return trans;
	}

	/**
		Invoked by {@link Store#_exec} to remove unlocked transient objects.
	*/
	sweep() {
		const property = this.$$();
		const keys = property._keyed.keysArray();

		for (let i=0, t; t=this[keys[i]]; i++) {
			if (!t.isLocked()) {
				this.delete(keys[i]);
			}
		}
	}

	/**
		Gets an [Iterator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators)
		object that contains the {@link TransientShadow} instances.
	*/
	values() {
		return iterateOver(this.__().keys(), key => this[key]);
	}

	[Symbol.iterator]() { return this.entries() }
}


/**
	The property representing {@link Store#transients}

	@see {@link TransientsShadow}
*/
export default class TransientsProperty extends ObjectProperty {
	constructor(type) {
		super(type);

		this.setShadowClass(TransientsShadow);
	}
}


StateType.defineType(TransientsProperty, spec => {
	spec.initialState({})
		.autoshadowOff
		.readonly
		.typeName("TransientsProperty");
});