From e73b9ce1f581121f262879dbd53c22bee129202f Mon Sep 17 00:00:00 2001 From: JC Brand Date: Thu, 26 Oct 2023 17:12:31 +0200 Subject: [PATCH] Fix type errors, add type definitions and remove overview.js --- Makefile | 2 + package.json | 1 + src/collection.js | 111 +++---- src/eventemitter.js | 5 + src/model.js | 2 +- src/overview.js | 191 ----------- src/storage.js | 4 +- src/types/collection.d.ts | 371 ++++++++++++++++++++++ src/types/collection.d.ts.map | 1 + src/types/drivers/sessionStorage.d.ts | 26 ++ src/types/drivers/sessionStorage.d.ts.map | 1 + src/types/element.d.ts | 111 +++++++ src/types/element.d.ts.map | 1 + src/types/eventemitter.d.ts | 93 ++++++ src/types/eventemitter.d.ts.map | 1 + src/types/helpers.d.ts | 62 ++++ src/types/helpers.d.ts.map | 1 + src/types/index.d.ts | 18 ++ src/types/index.d.ts.map | 1 + src/types/listening.d.ts | 40 +++ src/types/listening.d.ts.map | 1 + src/types/model.d.ts | 233 ++++++++++++++ src/types/model.d.ts.map | 1 + src/types/storage.d.ts | 34 ++ src/types/storage.d.ts.map | 1 + src/types/utils/events.d.ts | 28 ++ src/types/utils/events.d.ts.map | 1 + tsconfig.json | 7 +- 28 files changed, 1095 insertions(+), 254 deletions(-) delete mode 100644 src/overview.js create mode 100644 src/types/collection.d.ts create mode 100644 src/types/collection.d.ts.map create mode 100644 src/types/drivers/sessionStorage.d.ts create mode 100644 src/types/drivers/sessionStorage.d.ts.map create mode 100644 src/types/element.d.ts create mode 100644 src/types/element.d.ts.map create mode 100644 src/types/eventemitter.d.ts create mode 100644 src/types/eventemitter.d.ts.map create mode 100644 src/types/helpers.d.ts create mode 100644 src/types/helpers.d.ts.map create mode 100644 src/types/index.d.ts create mode 100644 src/types/index.d.ts.map create mode 100644 src/types/listening.d.ts create mode 100644 src/types/listening.d.ts.map create mode 100644 src/types/model.d.ts create mode 100644 src/types/model.d.ts.map create mode 100644 src/types/storage.d.ts create mode 100644 src/types/storage.d.ts.map create mode 100644 src/types/utils/events.d.ts create mode 100644 src/types/utils/events.d.ts.map diff --git a/Makefile b/Makefile index c2d3d98..b04391e 100644 --- a/Makefile +++ b/Makefile @@ -14,11 +14,13 @@ node_modules: package.json package-lock.json npm install build: node_modules + npm run types npm run build dist: build check: node_modules build eslint + npm run types npm run test .PHONY: eslint diff --git a/package.json b/package.json index 412d1e7..bf0bba3 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "description": "Modernized Backbone with web components", "url": "https://github.com/conversejs/skeletor", "main": "src/index.js", + "types": "src/types/index.d.ts", "browser": "dist/skeletor.js", "keywords": [ "model", diff --git a/src/collection.js b/src/collection.js index 1ad726d..ef6180a 100644 --- a/src/collection.js +++ b/src/collection.js @@ -51,6 +51,8 @@ class Collection extends EventEmitter(Object) { this._reset(); this.initialize.apply(this, arguments); if (models) this.reset(models, Object.assign({ silent: true }, options)); + + this[Symbol.iterator] = this.values; } /** @@ -280,10 +282,10 @@ class Collection extends EventEmitter(Object) { console.error(e); resolve(); }, - }) + }), ); }); - }) + }), ); await this.browserStorage.clear(); this.reset(); @@ -402,7 +404,7 @@ class Collection extends EventEmitter(Object) { sortBy(iteratee) { return sortBy( this.models, - isFunction(iteratee) ? iteratee : (m) => (isString(iteratee) ? m.get(iteratee) : m.matches(iteratee)) + isFunction(iteratee) ? iteratee : (m) => (isString(iteratee) ? m.get(iteratee) : m.matches(iteratee)), ); } @@ -452,7 +454,7 @@ class Collection extends EventEmitter(Object) { findLastIndex(pred, fromIndex) { return this.models.findLastIndex( isFunction(pred) ? pred : (m) => (isString(pred) ? m.get(pred) : m.matches(pred)), - fromIndex + fromIndex, ); } @@ -718,7 +720,7 @@ class Collection extends EventEmitter(Object) { _prepareModel(attrs, options) { if (this._isModel(attrs)) { if (!attrs.collection) attrs.collection = this; - return /** @type {Model} */(attrs); + return /** @type {Model} */ (attrs); } options = options ? clone(options) : {}; options.collection = this; @@ -822,26 +824,6 @@ class Collection extends EventEmitter(Object) { } } -// Defining an @@iterator method implements JavaScript's Iterable protocol. -// In modern ES2015 browsers, this value is found at Symbol.iterator. -const $$iterator = typeof Symbol === 'function' && Symbol.iterator; -if ($$iterator) { - Collection.prototype[$$iterator] = Collection.prototype.values; -} - -// CollectionIterator -// ------------------ - -// A CollectionIterator implements JavaScript's Iterator protocol, allowing the -// use of `for of` loops in modern browsers and interoperation between -// Collection and other JavaScript functions and third-party libraries -// which can operate on Iterables. -const CollectionIterator = function (collection, kind) { - this._collection = collection; - this._kind = kind; - this._index = 0; -}; - // This "enum" defines the three possible kinds of values which can be emitted // by a CollectionIterator that correspond to the values(), keys() and entries() // methods on Collection, respectively. @@ -849,42 +831,53 @@ const ITERATOR_VALUES = 1; const ITERATOR_KEYS = 2; const ITERATOR_KEYSVALUES = 3; -// All Iterators should themselves be Iterable. -if ($$iterator) { - CollectionIterator.prototype[$$iterator] = function () { - return this; - }; -} - -CollectionIterator.prototype.next = function () { - if (this._collection) { - // Only continue iterating if the iterated collection is long enough. - if (this._index < this._collection.length) { - const model = this._collection.at(this._index); - this._index++; - - // Construct a value depending on what kind of values should be iterated. - let value; - if (this._kind === ITERATOR_VALUES) { - value = model; - } else { - const id = this._collection.modelId(model.attributes); - if (this._kind === ITERATOR_KEYS) { - value = id; - } else { - // ITERATOR_KEYSVALUES - value = [id, model]; +class CollectionIterator { + /** + * A CollectionIterator implements JavaScript's Iterator protocol, allowing the + * use of `for of` loops in modern browsers and interoperation between + * Collection and other JavaScript functions and third-party libraries + * which can operate on Iterables. + */ + constructor(collection, kind) { + this._collection = collection; + this._kind = kind; + this._index = 0; + } + + [Symbol.iterator]() { + return { + next: () => { + if (this._collection) { + // Only continue iterating if the iterated collection is long enough. + if (this._index < this._collection.length) { + const model = this._collection.at(this._index); + this._index++; + + // Construct a value depending on what kind of values should be iterated. + let value; + if (this._kind === ITERATOR_VALUES) { + value = model; + } else { + const id = this._collection.modelId(model.attributes); + if (this._kind === ITERATOR_KEYS) { + value = id; + } else { + // ITERATOR_KEYSVALUES + value = [id, model]; + } + } + return { value: value, done: false }; + } + + // Once exhausted, remove the reference to the collection so future + // calls to the next method always return done. + this._collection = undefined; } - } - return { value: value, done: false }; - } - // Once exhausted, remove the reference to the collection so future - // calls to the next method always return done. - this._collection = undefined; + return { value: undefined, done: true }; + }, + }; } - - return { value: undefined, done: true }; -}; +} export { Collection }; diff --git a/src/eventemitter.js b/src/eventemitter.js index 8456377..7906bb8 100644 --- a/src/eventemitter.js +++ b/src/eventemitter.js @@ -11,6 +11,11 @@ import { eventsApi, onApi, offApi, onceMap, tryCatchOn, triggerApi } from './uti // A private global variable to share between listeners and listenees. let _listening; +/** + * @function + * @template {new(...args: any[]) => {}} ClassConstructor + * @param {ClassConstructor} Base + */ export function EventEmitter(Base) { return class EventEmitter extends Base { /** diff --git a/src/model.js b/src/model.js index f49ae53..680b0e7 100644 --- a/src/model.js +++ b/src/model.js @@ -360,7 +360,7 @@ class Model extends EventEmitter(Object) { * If the server returns an attributes hash that differs, the model's * state will be `set` again. * @param {string} key - * @param {string|Options} val + * @param {string|Options} [val] * @param {Options} [options] */ save(key, val, options) { diff --git a/src/overview.js b/src/overview.js deleted file mode 100644 index df61482..0000000 --- a/src/overview.js +++ /dev/null @@ -1,191 +0,0 @@ -/*! - * Copyright (c) JC Brand - */ -import debounce from 'lodash-es/debounce.js'; -import difference from 'lodash-es/difference.js'; -import drop from 'lodash-es/drop.js'; -import every from 'lodash-es/every.js'; -import extend from 'lodash-es/extend.js'; -import filter from 'lodash-es/filter.js'; -import find from 'lodash-es/find.js'; -import first from 'lodash-es/first.js'; -import forEach from 'lodash-es/forEach.js'; -import get from 'lodash-es/get.js'; -import head from 'lodash-es/head.js'; -import includes from 'lodash-es/includes.js'; -import indexOf from 'lodash-es/indexOf.js'; -import initial from 'lodash-es/initial.js'; -import invoke from 'lodash-es/invoke.js'; -import isEmpty from 'lodash-es/isEmpty.js'; -import last from 'lodash-es/last.js'; -import lastIndexOf from 'lodash-es/lastIndexOf.js'; -import map from 'lodash-es/map.js'; -import max from 'lodash-es/max.js'; -import min from 'lodash-es/min.js'; -import reduce from 'lodash-es/reduce.js'; -import reduceRight from 'lodash-es/reduceRight.js'; -import reject from 'lodash-es/reject.js'; -import rest from 'lodash-es/rest.js'; -import sample from 'lodash-es/sample.js'; -import shuffle from 'lodash-es/shuffle.js'; -import size from 'lodash-es/size.js'; -import some from 'lodash-es/some.js'; -import sortBy from 'lodash-es/sortBy.js'; -import tail from 'lodash-es/tail.js'; -import take from 'lodash-es/take.js'; -import toArray from 'lodash-es/toArray.js'; -import without from 'lodash-es/without.js'; -import { View } from "./view"; - - -const Overview = function (options) { - /* An Overview is a View that contains and keeps track of sub-views. - * Kind of like what a Collection is to a Model. - */ - this.views = {}; - this.keys = () => Object.keys(this.views); - this.getAll = () => this.views; - this.get = id => this.views[id]; - - /* Exclusive get. Returns all instances except the given id. */ - this.xget = id => { - return this.keys() - .filter(k => (k !== id)) - .reduce((acc, k) => { - acc[k] = this.views[k] - return acc; - }, {}); - } - - this.add = (id, view) => { - this.views[id] = view; - return view; - }; - - this.remove = id => { - if (typeof id === "undefined") { - new View().remove.apply(this); - } - const view = this.views[id]; - if (view) { - delete this.views[id]; - view.remove(); - return view; - } - }; - - this.removeAll = () => { - this.keys().forEach(id => this.remove(id)); - return this; - } - - View.apply(this, Array.prototype.slice.apply(arguments)); -}; - - -const methods = { - includes, difference, drop, - every, filter, find, - first, forEach, head, - indexOf, initial, invoke, isEmpty, - last, lastIndexOf, map, max, min, reduce, - reduceRight, reject, rest, sample, - shuffle, size, some, sortBy, tail, take, - toArray, without -} -Object.keys(methods).forEach(name => { - Overview.prototype[name] = function() { - const args = Array.prototype.slice.call(arguments); - args.unshift(this.views); - return methods[name].apply(this, args); - }; -}); - -Object.assign(Overview.prototype, View.prototype); -Overview.extend = View.extend; - - -const OrderedListView = Overview.extend({ - /* An OrderedListView is a special type of Overview which adds some - * methods and conventions for rendering an ordered list of elements. - */ - // The `listItems` attribute denotes the path (from this View) to the - // list of items. - listItems: 'model', - // The `sortEvent` attribute specifies the event which should cause the - // ordered list to be sorted. - sortEvent: 'change', - // If false, we debounce sorting and inserting the new item - // (for improved performance when a large amount of items get added all at once) - // Otherwise we immediately sort the items and insert the new item. - sortImmediatelyOnAdd: false, - // The `listSelector` is the selector used to query for the DOM list - // element which contains the ordered items. - listSelector: '.ordered-items', - // The `itemView` is constructor which should be called to create a - // View for a new item. - ItemView: undefined, - // The `subviewIndex` is the attribute of the list element model which - // acts as the index of the subview in the overview. - // An overview is a "Collection" of views, and they can be retrieved - // via an index. By default this is the 'id' attribute, but it could be - // set to something else. - subviewIndex: 'id', - - initialize () { - this.sortEventually = debounce(() => this.sortAndPositionAllItems(), 100); - this.items = get(this, this.listItems); - this.items.on('remove', this.removeView, this); - this.items.on('reset', this.removeAll, this); - - this.items.on('add', (a, b) => { - if (this.sortImmediatelyOnAdd) { - this.sortAndPositionAllItems(); - } else { - this.sortEventually(); - } - }); - - if (this.sortEvent) { - this.items.on(this.sortEvent, this.sortEventually, this); - } - }, - - createItemView (item) { - let item_view = this.get(item.get(this.subviewIndex)); - if (!item_view) { - item_view = new this.ItemView({model: item}); - this.add(item.get(this.subviewIndex), item_view); - } else { - item_view.model = item; - item_view.initialize(); - } - item_view.render(); - return item_view; - }, - - removeView (item) { - this.remove(item.get(this.subviewIndex)); - }, - - sortAndPositionAllItems () { - if (!this.items.length) { - return; - } - this.items.sort(); - - const list_el = this.el.querySelector(this.listSelector); - const div = document.createElement('div'); - list_el.parentNode.replaceChild(div, list_el); - this.items.forEach(item => { - let view = this.get(item.get(this.subviewIndex)); - if (!view) { - view = this.createItemView(item) - } - list_el.insertAdjacentElement('beforeend', view.el); - }); - div.parentNode.replaceChild(list_el, div); - } -}); - -export { OrderedListView, Overview } diff --git a/src/storage.js b/src/storage.js index 26eb96e..f64179d 100644 --- a/src/storage.js +++ b/src/storage.js @@ -8,7 +8,7 @@ import localForage from 'localforage/src/localforage'; import mergebounce from 'mergebounce'; import sessionStorageWrapper from './drivers/sessionStorage.js'; import { extendPrototype as extendPrototypeWithSetItems } from 'localforage-setitems'; -import { extendPrototype as extendPrototypeWithGetItems } from '@converse/localforage-getitems'; +import { extendPrototype as extendPrototypeWithGetItems } from '@converse/localforage-getitems/dist/localforage-getitems.es6'; import { guid } from './helpers.js'; const IN_MEMORY = memoryDriver._driver; @@ -111,7 +111,7 @@ class Storage { // the attributes dance again. model.attributes = new_attributes; } - promise = that.update(model, options); + promise = that.update(model); if (options.wait) { model.attributes = original_attributes; } diff --git a/src/types/collection.d.ts b/src/types/collection.d.ts new file mode 100644 index 0000000..71b131a --- /dev/null +++ b/src/types/collection.d.ts @@ -0,0 +1,371 @@ +export type Options = Record; +export type Attributes = Record; +export type Storage = import('./storage.js').default; +export type CollectionOptions = Record; +declare const Collection_base: { + new (...args: any[]): { + on(name: string, callback: (event: any, model: Model, collection: Collection, options: Record) => any, context: any): any; + _events: any; /** + * Create a new **Collection**, perhaps to contain a specific type of `model`. + * If a `comparator` is specified, the Collection will maintain + * its models in sort order, as they're added and removed. + * @param {Model[]} models + * @param {CollectionOptions} options + */ + _listeners: {}; + listenTo(obj: any, name: string, callback?: (event: any, model: Model, collection: Collection, options: Record) => any): any; + _listeningTo: {}; + _listenId: any; + off(name: string, callback: (event: any, model: Model, collection: Collection, options: Record) => any, context?: any): any; + stopListening(obj?: any, name?: string, callback?: (event: any, model: Model, collection: Collection, options: Record) => any): any; + once(name: string, callback: (event: any, model: Model, collection: Collection, options: Record) => any, context: any): any; + listenToOnce(obj: any, name: string, callback?: (event: any, model: Model, collection: Collection, options: Record) => any): any; + trigger(name: string, ...args: any[]): any; + }; +} & ObjectConstructor; +/** + * @typedef {Record.} Options + * @typedef {Record.} Attributes + * + * @typedef {import('./storage.js').default} Storage + * + * @typedef {Record.} CollectionOptions + * @property {Model} [model] + * @property {Function} [comparator] + */ +/** + * If models tend to represent a single row of data, a Collection is + * more analogous to a table full of data ... or a small slice or page of that + * table, or a collection of rows that belong together for a particular reason + * -- all of the messages in this particular folder, all of the documents + * belonging to this particular author, and so on. Collections maintain + * indexes of their models, both in order, and for lookup by `id`. + */ +export class Collection extends Collection_base { + /** + * Create a new **Collection**, perhaps to contain a specific type of `model`. + * If a `comparator` is specified, the Collection will maintain + * its models in sort order, as they're added and removed. + * @param {Model[]} models + * @param {CollectionOptions} options + */ + constructor(models: Model[], options: CollectionOptions, ...args: any[]); + _model: any; + comparator: any; + /** + * @param {Storage} storage + */ + set browserStorage(arg: import("./storage.js").default); + /** + * @returns {Storage} storage + */ + get browserStorage(): import("./storage.js").default; + _browserStorage: import("./storage.js").default; + /** + * @param {Model} model + */ + set model(arg: typeof Model); + /** + * The default model for a collection is just a **Model**. + * This should be overridden in most cases. + * @returns {typeof Model} + */ + get model(): typeof Model; + get length(): any; + /** + * preinitialize is an empty function by default. You can override it with a function + * or object. preinitialize will run before any instantiation logic is run in the Collection. + */ + preinitialize(): void; + /** + * Initialize is an empty function by default. Override it with your own + * initialization logic. + */ + initialize(): void; + /** + * The JSON representation of a Collection is an array of the + * models' attributes. + *@param {Options} options + */ + toJSON(options: Options): any; + /** + *@param {string} method + *@param {Model|Collection} model + *@param {Options} options + */ + sync(method: string, model: Model | Collection, options: Options): any; + /** + * Add a model, or list of models to the set. `models` may be + * Models or raw JavaScript objects to be converted to Models, or any + * combination of the two. + *@param {Model[]|Model|Attributes|Attributes[]} models + *@param {Options} options + */ + add(models: Model[] | Model | Attributes | Attributes[], options: Options): any; + /** + * Remove a model, or a list of models from the set. + * @param {Model|Model[]} models + * @param {Options} options + */ + remove(models: Model | Model[], options: Options): any; + /** + * Update a collection by `set`-ing a new list of models, adding new ones, + * removing models that are no longer present, and merging models that + * already exist in the collection, as necessary. Similar to **Model#set**, + * the core operation for updating the data contained by the collection. + *@param {Model[]|Model|Attributes|Attributes[]} models + * @param {Options} options + */ + set(models: Model[] | Model | Attributes | Attributes[], options: Options): any; + clearStore(options?: {}, filter?: (o: any) => any): Promise; + /** + * When you have more items than you want to add or remove individually, + * you can reset the entire set with a new list of models, without firing + * any granular `add` or `remove` events. Fires `reset` when finished. + * Useful for bulk operations and optimizations. + * @param {Model|Model[]} [models] + * @param {Options} [options] + */ + reset(models?: Model | Model[], options?: Options): Model | Model[]; + /** + * Add a model to the end of the collection. + * @param {Model} model + * @param {Options} [options] + */ + push(model: Model, options?: Options): any; + /** + * Remove a model from the end of the collection. + * @param {Options} [options] + */ + pop(options?: Options): any; + /** + * Add a model to the beginning of the collection. + * @param {Model} model + * @param {Options} [options] + */ + unshift(model: Model, options?: Options): any; + /** + * Remove a model from the beginning of the collection. + * @param {Options} [options] + */ + shift(options?: Options): any; + /** Slice out a sub-array of models from the collection. */ + slice(...args: any[]): any; + /** + * @param {Function|Object} callback + * @param {any} thisArg + */ + filter(callback: Function | any, thisArg: any): any; + /** + * @param {Function} pred + */ + every(pred: Function): any; + /** + * @param {Model[]} values + */ + difference(values: Model[]): any; + max(): any; + min(): any; + drop(n?: number): any; + /** + * @param {Function|Object} pred + */ + some(pred: Function | any): any; + sortBy(iteratee: any): any; + isEmpty(): boolean; + keyBy(iteratee: any): any; + each(callback: any, thisArg: any): any; + forEach(callback: any, thisArg: any): any; + includes(item: any): any; + size(): any; + countBy(f: any): any; + groupBy(pred: any): any; + /** + * @param {number} fromIndex + */ + indexOf(fromIndex: number): any; + /** + * @param {Function|string|RegExp} pred + * @param {number} fromIndex + */ + findLastIndex(pred: Function | string | RegExp, fromIndex: number): any; + /** + * @param {number} fromIndex + */ + lastIndexOf(fromIndex: number): any; + /** + * @param {Function|string|RegExp} pred + */ + findIndex(pred: Function | string | RegExp): any; + last(): any; + head(): any; + first(): any; + map(cb: any, thisArg: any): any; + reduce(callback: any, initialValue: any): any; + reduceRight(callback: any, initialValue: any): any; + toArray(): any[]; + /** + * Get a model from the set by id, cid, model object with id or cid + * properties, or an attributes object that is transformed through modelId. + * @param {string|number|Object|Model} obj + */ + get(obj: string | number | any | Model): any; + /** + * Returns `true` if the model is in the collection. + * @param {string|number|Object|Model} obj + */ + has(obj: string | number | any | Model): boolean; + /** + * Get the model at the given index. + * @param {number} index + */ + at(index: number): any; + /** + * Return models with matching attributes. Useful for simple cases of + * `filter`. + * @param {Attributes} attrs + * @param {boolean} first + */ + where(attrs: Attributes, first: boolean): any; + /** + * Return the first model with matching attributes. Useful for simple cases + * of `find`. + * @param {Attributes} attrs + */ + findWhere(attrs: Attributes): any; + /** + * @param {Attributes} predicate + * @param {number} [fromIndex] + */ + find(predicate: Attributes, fromIndex?: number): any; + /** + * Force the collection to re-sort itself. You don't need to call this under + * normal circumstances, as the set will maintain sort order as each item + * is added. + * @param {Options} options + */ + sort(options: Options): this; + models: any; + /** + * Pluck an attribute from each model in the collection. + * @param {string} attr + */ + pluck(attr: string): any; + /** + * Fetch the default set of models for this collection, resetting the + * collection when they arrive. If `reset: true` is passed, the response + * data will be passed through the `reset` method instead of `set`. + * @param {Options} options + */ + fetch(options: Options): any; + /** + * Create a new instance of a model in this collection. Add the model to the + * collection immediately, unless `wait: true` is passed, in which case we + * wait for the server to agree. + * @param {Model|Attributes} model + * @param {Options} [options] + */ + create(model: Model | Attributes, options?: Options): false | Model | (Promise & { + isResolved: boolean; + isPending: boolean; + isRejected: boolean; + resolve: Function; + reject: Function; + }) | Attributes; + /** + * **parse** converts a response into a list of models to be added to the + * collection. The default implementation is just to pass it through. + * @param {Object} resp + * @param {Options} [options] + */ + parse(resp: any, options?: Options): any; + /** + * Define how to uniquely identify models in the collection. + * @param {Attributes} attrs + */ + modelId(attrs: Attributes): any; + /** Get an iterator of all models in this collection. */ + values(): CollectionIterator; + /** Get an iterator of all model IDs in this collection. */ + keys(): CollectionIterator; + /** Get an iterator of all [ID, model] tuples in this collection. */ + entries(): CollectionIterator; + /** + * Private method to reset all internal state. Called when the collection + * is first initialized or reset. + */ + _reset(): void; + _byId: {}; + /** + * @param {Attributes} attrs + * @param {Options} [options] + */ + createModel(attrs: Attributes, options?: Options): Model; + /** + * Prepare a hash of attributes (or other model) to be added to this + * collection. + * @param {Attributes|Model} attrs + * @param {Options} [options] + * @return {Model} + */ + _prepareModel(attrs: Attributes | Model, options?: Options): Model; + /** + * Internal method called by both remove and set. + * @param {Model[]} models + * @param {Options} [options] + */ + _removeModels(models: Model[], options?: Options): any[]; + /** + * Method for checking whether an object should be considered a model for + * the purposes of adding to the collection. + * @param {any} model + */ + _isModel(model: any): boolean; + /** + * Internal method to create a model's ties to a collection. + * @param {Model} model + * @param {Options} [options] + */ + _addReference(model: Model, options?: Options): void; + /** + * Internal method to sever a model's ties to a collection. + * @private + * @param {Model} model + * @param {Options} [options] + */ + private _removeReference; + /** + * Internal method called every time a model in the set fires an event. + * Sets need to update their indexes when models change ids. All other + * events simply proxy through. "add" and "remove" events that originate + * in other collections are ignored. + * @private + * @param {any} event + * @param {Model} model + * @param {Collection} collection + * @param {Options} [options] + */ + private _onModelEvent; + [Symbol.iterator]: () => CollectionIterator; +} +import { Model } from './model.js'; +declare class CollectionIterator { + /** + * A CollectionIterator implements JavaScript's Iterator protocol, allowing the + * use of `for of` loops in modern browsers and interoperation between + * Collection and other JavaScript functions and third-party libraries + * which can operate on Iterables. + */ + constructor(collection: any, kind: any); + _collection: any; + _kind: any; + _index: number; + [Symbol.iterator](): { + next: () => { + value: any; + done: boolean; + }; + }; +} +export {}; +//# sourceMappingURL=collection.d.ts.map \ No newline at end of file diff --git a/src/types/collection.d.ts.map b/src/types/collection.d.ts.map new file mode 100644 index 0000000..8f88b10 --- /dev/null +++ b/src/types/collection.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"collection.d.ts","sourceRoot":"","sources":["../collection.js"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/src/types/drivers/sessionStorage.d.ts b/src/types/drivers/sessionStorage.d.ts new file mode 100644 index 0000000..148fcc2 --- /dev/null +++ b/src/types/drivers/sessionStorage.d.ts @@ -0,0 +1,26 @@ +export default sessionStorageWrapper; +declare namespace sessionStorageWrapper { + export let _driver: string; + export { _initStorage }; + export let _support: boolean; + export { iterate }; + export { getItem }; + export { setItem }; + export { removeItem }; + export { clear }; + export { length }; + export { key }; + export { keys }; + export { dropInstance }; +} +declare function _initStorage(options: any): void; +declare function iterate(iterator: any, callback: any): any; +declare function getItem(key: any, callback: any): any; +declare function setItem(key: any, value: any, callback: any): Promise; +declare function removeItem(key: any, callback: any): any; +declare function clear(callback: any): any; +declare function length(callback: any): any; +declare function key(n: any, callback: any): any; +declare function keys(callback: any): any; +declare function dropInstance(options: any, callback: any, ...args: any[]): Promise; +//# sourceMappingURL=sessionStorage.d.ts.map \ No newline at end of file diff --git a/src/types/drivers/sessionStorage.d.ts.map b/src/types/drivers/sessionStorage.d.ts.map new file mode 100644 index 0000000..ea3b4d8 --- /dev/null +++ b/src/types/drivers/sessionStorage.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"sessionStorage.d.ts","sourceRoot":"","sources":["../../drivers/sessionStorage.js"],"names":[],"mappings":";;;;;;;;;;;;;;;AA0DA,kDAQC;AA2CD,4DA0CC;AA7DD,uDAgBC;AAkHD,6EA2BC;AAxCD,0DAOC;AAhJD,2CAeC;AA+GD,4CAQC;AAlDD,iDAoBC;AAED,0CAiBC;AAwDD,0FAiCC"} \ No newline at end of file diff --git a/src/types/element.d.ts b/src/types/element.d.ts new file mode 100644 index 0000000..ebd0721 --- /dev/null +++ b/src/types/element.d.ts @@ -0,0 +1,111 @@ +export default ElementView; +declare const ElementView_base: { + new (...args: any[]): { + on(name: string, callback: (event: any, model: import("./model.js").Model, collection: import("./collection.js").Collection, options?: Record) => any, context: any): any; + _events: any; + _listeners: {}; + listenTo(obj: any, name: string, callback?: (event: any, model: import("./model.js").Model, collection: import("./collection.js").Collection, options?: Record) => any): any; + _listeningTo: {}; + _listenId: any; + off(name: string, callback: (event: any, model: import("./model.js").Model, collection: import("./collection.js").Collection, options?: Record) => any, context?: any): any; + stopListening(obj?: any, name?: string, callback?: (event: any, model: import("./model.js").Model, collection: import("./collection.js").Collection, options?: Record) => any): any; + once(name: string, callback: (event: any, model: import("./model.js").Model, collection: import("./collection.js").Collection, options?: Record) => any, context: any): any; + listenToOnce(obj: any, name: string, callback?: (event: any, model: import("./model.js").Model, collection: import("./collection.js").Collection, options?: Record) => any): any; + trigger(name: string, ...args: any[]): any; + }; +} & { + new (): HTMLElement; + prototype: HTMLElement; +}; +declare class ElementView extends ElementView_base { + /** + * @param {Options} options + */ + constructor(options?: Record); + /** + * @typedef {import('./model.js').Model} Model + * @typedef {import('./collection.js').Collection} Collection + * @typedef {Record.} Options + * + * @callback EventCallback + * @param {any} event + * @param {Model} model + * @param {Collection} collection + * @param {Options} [options] + */ + set events(arg: {}); + get events(): {}; + _declarativeEvents: {}; + stopListening: any; + cid: any; + _domEvents: any[]; + createRenderRoot(): this; + connectedCallback(...args: any[]): void; + _initialized: boolean; + disconnectedCallback(): void; + /** + * preinitialize is an empty function by default. You can override it with a function + * or object. preinitialize will run before any instantiation logic is run in the View + * eslint-disable-next-line class-methods-use-this + */ + preinitialize(): void; + /** + * Initialize is an empty function by default. Override it with your own + * initialization logic. + */ + initialize(): void; + beforeRender(): void; + afterRender(): void; + /** + * **render** is the core function that your view should override, in order + * to populate its element (`this.el`), with the appropriate HTML. The + * convention is for **render** to always return `this`. + */ + render(): this; + toHTML(): string; + /** + * Set callbacks, where `this.events` is a hash of + * + * *{"event selector": "callback"}* + * + * { + * 'mousedown .title': 'edit', + * 'click .button': 'save', + * 'click .open': function(e) { ... } + * } + * + * pairs. Callbacks will be bound to the view, with `this` set properly. + * Uses event delegation for efficiency. + * Omitting the selector binds the event to `this.el`. + */ + delegateEvents(): this; + /** + * Make a event delegation handler for the given `eventName` and `selector` + * and attach it to `this.el`. + * If selector is empty, the listener will be bound to `this.el`. If not, a + * new handler that will recursively traverse up the event target's DOM + * hierarchy looking for a node that matches the selector. If one is found, + * the event's `delegateTarget` property is set to it and the return the + * result of calling bound `listener` with the parameters given to the + * handler. + * @param {string} eventName + * @param {string} selector + * @param {(ev: Event) => any} listener + */ + delegate(eventName: string, selector: string, listener: (ev: Event) => any): this | ((ev: Event) => any); + /** + * Clears all callbacks previously bound to the view by `delegateEvents`. + * You usually don't need to use this, but may wish to if you have multiple + * Backbone views attached to the same DOM element. + */ + undelegateEvents(): this; + /** + * A finer-grained `undelegateEvents` for removing a single delegated event. + * `selector` and `listener` are both optional. + * @param {string} eventName + * @param {string} selector + * @param {(ev: Event) => any} listener + */ + undelegate(eventName: string, selector: string, listener: (ev: Event) => any): this; +} +//# sourceMappingURL=element.d.ts.map \ No newline at end of file diff --git a/src/types/element.d.ts.map b/src/types/element.d.ts.map new file mode 100644 index 0000000..876caef --- /dev/null +++ b/src/types/element.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"element.d.ts","sourceRoot":"","sources":["../element.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;AAOA;IAsBE;;OAEG;IACH,2CAeC;IAtCD;;;;;;;;;;OAUG;IAEH,oBAEC;IAED,iBAEC;IALC,uBAAgC;IAchC,mBAAyB;IAIzB,SAA2B;IAE3B,kBAAoB;IAOtB,yBAGC;IAED,wCAOC;IAHG,sBAAwB;IAK5B,6BAGC;IAED;;;;OAIG;IACH,sBAAkB;IAElB;;;OAGG;IACH,mBAAe;IAEf,qBAAiB;IACjB,oBAAgB;IAEhB;;;;OAIG;IACH,eAKC;IAED,iBAEC;IAED;;;;;;;;;;;;;;OAcG;IACH,uBAaC;IAED;;;;;;;;;;;;OAYG;IACH,oBAJW,MAAM,YACN,MAAM,iBACD,KAAK,KAAK,GAAG,gBAAb,KAAK,KAAK,GAAG,EAsC5B;IAED;;;;OAIG;IACH,yBASC;IAED;;;;;;OAMG;IACH,sBAJW,MAAM,YACN,MAAM,iBACD,KAAK,KAAK,GAAG,QAyB5B;CACF"} \ No newline at end of file diff --git a/src/types/eventemitter.d.ts b/src/types/eventemitter.d.ts new file mode 100644 index 0000000..8c607c9 --- /dev/null +++ b/src/types/eventemitter.d.ts @@ -0,0 +1,93 @@ +/** + * @function + * @template {new(...args: any[]) => {}} ClassConstructor + * @param {ClassConstructor} Base + */ +export function EventEmitter {}>(Base: ClassConstructor): { + new (...args: any[]): { + /** + * @typedef {import('./model.js').Model} Model + * @typedef {import('./collection.js').Collection} Collection + * @typedef {Record.} Options + * + * @callback EventCallback + * @param {any} event + * @param {Model} model + * @param {Collection} collection + * @param {Options} [options] + */ + /** + * Bind an event to a `callback` function. Passing `"all"` will bind + * the callback to all events fired. + * @param {string} name + * @param {EventCallback} callback + * @param {any} context + * @return {EventEmitter} + */ + on(name: string, callback: (event: any, model: import("./model.js").Model, collection: import("./collection.js").Collection, options?: Record) => any, context: any): any; + _events: any; + _listeners: {}; + /** + * Inversion-of-control versions of `on`. Tell *this* object to listen to + * an event in another object... keeping track of what it's listening to + * for easier unbinding later. + * @param {any} obj + * @param {string} name + * @param {EventCallback} [callback] + * @return {EventEmitter} + */ + listenTo(obj: any, name: string, callback?: (event: any, model: import("./model.js").Model, collection: import("./collection.js").Collection, options?: Record) => any): any; + _listeningTo: {}; + _listenId: any; + /** + * Remove one or many callbacks. If `context` is null, removes all + * callbacks with that function. If `callback` is null, removes all + * callbacks for the event. If `name` is null, removes all bound + * callbacks for all events. + * @param {string} name + * @param {EventCallback} callback + * @param {any} [context] + * @return {EventEmitter} + */ + off(name: string, callback: (event: any, model: import("./model.js").Model, collection: import("./collection.js").Collection, options?: Record) => any, context?: any): any; + /** + * Tell this object to stop listening to either specific events ... or + * to every object it's currently listening to. + * @param {any} [obj] + * @param {string} [name] + * @param {EventCallback} [callback] + * @return {EventEmitter} + */ + stopListening(obj?: any, name?: string, callback?: (event: any, model: import("./model.js").Model, collection: import("./collection.js").Collection, options?: Record) => any): any; + /** + * Bind an event to only be triggered a single time. After the first time + * the callback is invoked, its listener will be removed. If multiple events + * are passed in using the space-separated syntax, the handler will fire + * once for each event, not once for a combination of all events. + * @param {string} name + * @param {EventCallback} callback + * @param {any} context + * @return {EventEmitter} + */ + once(name: string, callback: (event: any, model: import("./model.js").Model, collection: import("./collection.js").Collection, options?: Record) => any, context: any): any; + /** + * Inversion-of-control versions of `once`. + * @param {any} obj + * @param {string} name + * @param {EventCallback} [callback] + * @return {EventEmitter} + */ + listenToOnce(obj: any, name: string, callback?: (event: any, model: import("./model.js").Model, collection: import("./collection.js").Collection, options?: Record) => any): any; + /** + * Trigger one or many events, firing all bound callbacks. Callbacks are + * passed the same arguments as `trigger` is, apart from the event name + * (unless you're listening on `"all"`, which will cause your callback to + * receive the true name of the event as the first argument). + * @param {string} name + * @return {EventEmitter} + */ + trigger(name: string, ...args: any[]): any; + }; +} & ClassConstructor; +export default EventEmitter; +//# sourceMappingURL=eventemitter.d.ts.map \ No newline at end of file diff --git a/src/types/eventemitter.d.ts.map b/src/types/eventemitter.d.ts.map new file mode 100644 index 0000000..acf6bfd --- /dev/null +++ b/src/types/eventemitter.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"eventemitter.d.ts","sourceRoot":"","sources":["../eventemitter.js"],"names":[],"mappings":"AAaA;;;;GAIG;AACH,oEAH2B,GAAG,EAAE,KAAK,EAAE;kBAAZ,GAAG,EAAE;QAK5B;;;;;;;;;;WAUG;QAEH;;;;;;;WAOG;iBAJQ,MAAM,oBATN,GAAG,uIAWH,GAAG;;;QAqBd;;;;;;;;WAQG;sBAJQ,GAAG,QACH,MAAM,qBArCN,GAAG;;;QAiEd;;;;;;;;;WASG;kBAJQ,MAAM,oBAtEN,GAAG,wIAwEH,GAAG;QAad;;;;;;;WAOG;4BAJQ,GAAG,SACH,MAAM,qBAzFN,GAAG;QAiHd;;;;;;;;;WASG;mBAJQ,MAAM,oBAtHN,GAAG,uIAwHH,GAAG;QAUd;;;;;;WAMG;0BAJQ,GAAG,QACH,MAAM,qBArIN,GAAG;QA+Id;;;;;;;WAOG;sBAFQ,MAAM;;qBAUpB"} \ No newline at end of file diff --git a/src/types/helpers.d.ts b/src/types/helpers.d.ts new file mode 100644 index 0000000..124dfb7 --- /dev/null +++ b/src/types/helpers.d.ts @@ -0,0 +1,62 @@ +export function guid(): string; +export function inherits(protoProps: any, staticProps: any): any; +export function getResolveablePromise(): Promise & { + isResolved: boolean; + isPending: boolean; + isRejected: boolean; + resolve: Function; + reject: Function; +}; +export function urlError(): void; +export function wrapError(model: any, options: any): void; +/** + * @typedef {import('./model.js').Model} Model + * @typedef {import('./collection.js').Collection} Collection + */ +/** + * @param {Model | Collection} model + */ +export function getSyncMethod(model: Model | Collection): any; +/** + * @typedef {Object} SyncOptions + * @property {string} [url] + * @property {any} [data] + * @property {any} [attrs] + * @property {Function} [success] + * @property {Function} [error] + * @property {any} [xhr] + */ +/** + * Override this function to change the manner in which Backbone persists + * models to the server. You will be passed the type of request, and the + * model in question. By default makes a `fetch()` API call + * to the model's `url()`. + * + * Some possible customizations could be: + * + * - Use `setTimeout` to batch rapid-fire updates into a single request. + * - Persist models via WebSockets instead of Ajax. + * - Persist models to browser storage + * + * @param {'create'|'update'|'patch'} method + * @param {import('./model.js').Model} model + * @param {SyncOptions} [options] + */ +export function sync(method: 'create' | 'update' | 'patch', model: import('./model.js').Model, options?: SyncOptions): Promise; +/** + * Custom error for indicating timeouts + * @namespace _converse + */ +export class NotImplementedError extends Error { +} +export type Model = import('./model.js').Model; +export type Collection = import('./collection.js').Collection; +export type SyncOptions = { + url?: string; + data?: any; + attrs?: any; + success?: Function; + error?: Function; + xhr?: any; +}; +//# sourceMappingURL=helpers.d.ts.map \ No newline at end of file diff --git a/src/types/helpers.d.ts.map b/src/types/helpers.d.ts.map new file mode 100644 index 0000000..da81755 --- /dev/null +++ b/src/types/helpers.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../helpers.js"],"names":[],"mappings":"AAkBA,+BAGC;AASD,iEA6BC;AAED;gBAGgB,OAAO;eACP,OAAO;gBACP,OAAO;;;EAwCtB;AAGD,iCAEC;AAGD,0DAMC;AAWD;;;GAGG;AAGH;;GAEG;AACH,qCAFW,KAAK,GAAG,UAAU,OAK5B;AAED;;;;;;;;GAQG;AAEH;;;;;;;;;;;;;;;GAeG;AACH,6BAJW,QAAQ,GAAC,QAAQ,GAAC,OAAO,SACzB,OAAO,YAAY,EAAE,KAAK,YAC1B,WAAW,qBAsBrB;AAxLD;;;GAGG;AACH;CAAiD;oBAyHpC,OAAO,YAAY,EAAE,KAAK;yBAC1B,OAAO,iBAAiB,EAAE,UAAU;;UAcnC,MAAM;WACN,GAAG;YACH,GAAG;;;UAGH,GAAG"} \ No newline at end of file diff --git a/src/types/index.d.ts b/src/types/index.d.ts new file mode 100644 index 0000000..c605551 --- /dev/null +++ b/src/types/index.d.ts @@ -0,0 +1,18 @@ +export default skeletor; +declare namespace skeletor { + let VERSION: string; + function noConflict(): { + Collection: typeof Collection; + ElementView: typeof ElementView; + EventEmitter: typeof EventEmitter; + Model: typeof Model; + sync: typeof sync; + }; +} +import { Collection } from './collection.js'; +import ElementView from './element.js'; +import EventEmitter from './eventemitter.js'; +import { Model } from './model.js'; +import { sync } from './helpers.js'; +export { Collection, ElementView, EventEmitter, Model, sync }; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/src/types/index.d.ts.map b/src/types/index.d.ts.map new file mode 100644 index 0000000..820e720 --- /dev/null +++ b/src/types/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.js"],"names":[],"mappings":";;;IA8BA;;;;;;MAGC;;2BA9B0B,iBAAiB;wBAFpB,cAAc;yBACb,mBAAmB;sBAEtB,YAAY;qBACb,cAAc"} \ No newline at end of file diff --git a/src/types/listening.d.ts b/src/types/listening.d.ts new file mode 100644 index 0000000..f954063 --- /dev/null +++ b/src/types/listening.d.ts @@ -0,0 +1,40 @@ +export default Listening; +/** + * A listening class that tracks and cleans up memory bindings + * when all callbacks have been offed. + */ +declare class Listening { + /** @typedef {import('./eventemitter.js').default} EventEmitter */ + /** + * @param {any} listener + * @param {any} obj + */ + constructor(listener: any, obj: any); + id: any; + listener: any; + obj: any; + interop: boolean; + count: number; + _events: any; + /** + * @param {string} name + * @param {Function} callback + * @param {any} context + * @param {Listening} _listening + */ + start(name: string, callback: Function, context: any, _listening: Listening): this; + /** + * Stop's listening to a callback (or several). + * Uses an optimized counter if the listenee uses Backbone.Events. + * Otherwise, falls back to manual tracking to support events + * library interop. + * @param {string} name + * @param {Function} callback + */ + stop(name: string, callback: Function): void; + /** + * Cleans up memory bindings between the listener and the listenee. + */ + cleanup(): void; +} +//# sourceMappingURL=listening.d.ts.map \ No newline at end of file diff --git a/src/types/listening.d.ts.map b/src/types/listening.d.ts.map new file mode 100644 index 0000000..346d043 --- /dev/null +++ b/src/types/listening.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"listening.d.ts","sourceRoot":"","sources":["../listening.js"],"names":[],"mappings":";AAEA;;;GAGG;AACH;IAEE,kEAAkE;IAElE;;;OAGG;IACH,sBAHW,GAAG,OACH,GAAG,EASb;IANC,QAA4B;IAC5B,cAAwB;IACxB,SAAc;IACd,iBAAmB;IACnB,cAAc;IACd,aAAwB;IAG1B;;;;;OAKG;IACH,YALW,MAAM,+BAEN,GAAG,cACH,SAAS,QAmBnB;IAED;;;;;;;OAOG;IACH,WAHW,MAAM,4BAgBhB;IAED;;OAEG;IACH,gBAGC;CACF"} \ No newline at end of file diff --git a/src/types/model.d.ts b/src/types/model.d.ts new file mode 100644 index 0000000..031a798 --- /dev/null +++ b/src/types/model.d.ts @@ -0,0 +1,233 @@ +export type Collection = import('./collection.js').Collection; +export type Attributes = Record; +export type Options = Record; +export type ModelOptions = Record; +declare const Model_base: { + new (...args: any[]): { + /** + * @typedef {import('./collection.js').Collection} Collection + * @typedef {Record.} Attributes + * + * @typedef {Record.} Options + * @property {boolean} [validate] + * + * @typedef {Record.} ModelOptions + * @property {Collection} [collection] + * @property {boolean} [parse] + * @property {boolean} [unset] + * @property {boolean} [silent] + */ + /** + * **Models** are the basic data object in the framework -- + * frequently representing a row in a table in a database on your server. + * A discrete chunk of data and a bunch of useful, related methods for + * performing computations and transformations on that data. + */ + on(name: string, callback: (event: any, model: Model, collection: import("./collection.js").Collection, options: Record) => any, context: any): any; + _events: any; + _listeners: {}; + listenTo(obj: any, name: string, callback?: (event: any, model: Model, collection: import("./collection.js").Collection, options: Record) => any): any; + _listeningTo: {}; + _listenId: any; + off(name: string, callback: (event: any, model: Model, collection: import("./collection.js").Collection, options: Record) => any, context?: any): any; + stopListening(obj?: any, name?: string, callback?: (event: any, model: Model, collection: import("./collection.js").Collection, options: Record) => any): any; + once(name: string, callback: (event: any, model: Model, collection: import("./collection.js").Collection, options: Record) => any, context: any): any; + listenToOnce(obj: any, name: string, callback?: (event: any, model: Model, collection: import("./collection.js").Collection, options: Record) => any): any; + trigger(name: string, ...args: any[]): any; + }; +} & ObjectConstructor; +/** + * @typedef {import('./collection.js').Collection} Collection + * @typedef {Record.} Attributes + * + * @typedef {Record.} Options + * @property {boolean} [validate] + * + * @typedef {Record.} ModelOptions + * @property {Collection} [collection] + * @property {boolean} [parse] + * @property {boolean} [unset] + * @property {boolean} [silent] + */ +/** + * **Models** are the basic data object in the framework -- + * frequently representing a row in a table in a database on your server. + * A discrete chunk of data and a bunch of useful, related methods for + * performing computations and transformations on that data. + */ +export class Model extends Model_base { + /** + * Create a new model with the specified attributes. A client id (`cid`) + * is automatically generated and assigned for you. + * @param {Attributes} attributes + * @param {ModelOptions} options + */ + constructor(attributes: Attributes, options: ModelOptions, ...args: any[]); + cid: any; + attributes: {}; + validationError: any; + validate: any; + collection: any; + changed: {}; + /** + * The default name for the JSON `id` attribute is `"id"`. MongoDB and + * CouchDB users may want to set this to `"_id"` (by overriding this getter + * in a subclass). + */ + get idAttribute(): string; + /** + * The prefix is used to create the client id which is used to identify models locally. + * You may want to override this if you're experiencing name clashes with model ids. + */ + get cidPrefix(): string; + /** + * preinitialize is an empty function by default. You can override it with a function + * or object. preinitialize will run before any instantiation logic is run in the Model. + */ + preinitialize(): void; + /** + * Initialize is an empty function by default. Override it with your own + * initialization logic. + */ + initialize(): void; + /** + * Return a copy of the model's `attributes` object. + */ + toJSON(): any; + /** + * Override this if you need custom syncing semantics for *this* particular model. + * @param {'create'|'update'|'patch'|'delete'|'read'} method + * @param {Model} model + * @param {Options} options + */ + sync(method: 'create' | 'update' | 'patch' | 'delete' | 'read', model: Model, options: Options): any; + /** + * Get the value of an attribute. + * @param {string} attr + */ + get(attr: string): any; + keys(): string[]; + values(): any[]; + pairs(): [string, any][]; + entries(): [string, any][]; + invert(): any; + pick(...args: any[]): any; + omit(...args: any[]): any; + isEmpty(): any; + /** + * Returns `true` if the attribute contains a value that is not null + * or undefined. + * @param {string} attr + */ + has(attr: string): boolean; + /** + * Special-cased proxy to lodash's `matches` method. + * @param {Attributes} attrs + */ + matches(attrs: Attributes): boolean; + /** + * Set a hash of model attributes on the object, firing `"change"`. This is + * the core primitive operation of a model, updating the data and notifying + * anyone who needs to know about the change in state. The heart of the beast. + * @param {string|Object} key + * @param {string|Object} val + * @param {Options} [options] + */ + set(key: string | any, val: string | any, options?: Options): false | this; + _changing: boolean; + _previousAttributes: any; + id: any; + _pending: boolean | Options; + /** + * Remove an attribute from the model, firing `"change"`. `unset` is a noop + * if the attribute doesn't exist. + * @param {string} attr + * @param {Options} options + */ + unset(attr: string, options: Options): false | this; + /** + * Clear all attributes on the model, firing `"change"`. + * @param {Options} options + */ + clear(options: Options): false | this; + /** + * Determine if the model has changed since the last `"change"` event. + * If you specify an attribute name, determine if that attribute has changed. + * @param {string} [attr] + */ + hasChanged(attr?: string): any; + /** + * Return an object containing all the attributes that have changed, or + * false if there are no changed attributes. Useful for determining what + * parts of a view need to be updated and/or what attributes need to be + * persisted to the server. Unset attributes will be set to undefined. + * You can also pass an attributes object to diff against the model, + * determining if there *would be* a change. + * @param {Object} diff + */ + changedAttributes(diff: any): any; + /** + * Get the previous value of an attribute, recorded at the time the last + * `"change"` event was fired. + * @param {string} [attr] + */ + previous(attr?: string): any; + /** + * Get all of the attributes of the model at the time of the previous + * `"change"` event. + */ + previousAttributes(): any; + /** + * Fetch the model from the server, merging the response with the model's + * local attributes. Any changed attributes will trigger a "change" event. + * @param {Options} options + */ + fetch(options: Options): any; + /** + * Set a hash of model attributes, and sync the model to the server. + * If the server returns an attributes hash that differs, the model's + * state will be `set` again. + * @param {string} key + * @param {string|Options} [val] + * @param {Options} [options] + */ + save(key: string, val?: string | Options, options?: Options): any; + /** + * Destroy this model on the server if it was already persisted. + * Optimistically removes the model from its collection, if it has one. + * If `wait: true` is passed, waits for the server to respond before removal. + * @param {Options} [options] + */ + destroy(options?: Options): boolean; + /** + * Default URL for the model's representation on the server -- if you're + * using Backbone's restful methods, override this to change the endpoint + * that will be called. + */ + url(): any; + /** + * **parse** converts a response into the hash of attributes to be `set` on + * the model. The default implementation is just to pass the response along. + * @param {Options} resp + * @param {Options} [options] + */ + parse(resp: Options, options?: Options): Options; + /** + * A model is new if it has never been saved to the server, and lacks an id. + */ + isNew(): boolean; + /** + * Check if the model is currently in a valid state. + * @param {Options} [options] + */ + isValid(options?: Options): boolean; + /** + * Run validation against the next complete set of model attributes, + * returning `true` if all is well. Otherwise, fire an `"invalid"` event. + * @param {Attributes} attrs + * @param {Options} [options] + */ + _validate(attrs: Attributes, options?: Options): boolean; +} +export {}; +//# sourceMappingURL=model.d.ts.map \ No newline at end of file diff --git a/src/types/model.d.ts.map b/src/types/model.d.ts.map new file mode 100644 index 0000000..5bf5324 --- /dev/null +++ b/src/types/model.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../model.js"],"names":[],"mappings":"yBAgBa,OAAO,iBAAiB,EAAE,UAAU;yBACpC,OAAQ,MAAM,EAAE,GAAG,CAAC;sBAEpB,OAAQ,MAAM,EAAE,GAAG,CAAC;2BAGpB,OAAQ,MAAM,EAAE,GAAG,CAAC;;;QAPjC;;;;;;;;;;;;WAYG;QAEH;;;;;WAKG;;;;;;;;;;;;;;AAnBH;;;;;;;;;;;;GAYG;AAEH;;;;;GAKG;AACH;IACE;;;;;OAKG;IACH,wBAHW,UAAU,WACV,YAAY,kBA2BtB;IApBC,SAAmC;IACnC,eAAoB;IAGpB,qBAA2B;IAE3B,cAAqC;IAEb,gBAAoC;IAW5D,YAAiB;IAGnB;;;;OAIG;IAEH,0BAEC;IAED;;;OAGG;IAEH,wBAEC;IAED;;;OAGG;IAEH,sBAAkB;IAElB;;;OAGG;IAEH,mBAAe;IAEf;;OAEG;IACH,cAEC;IAED;;;;;OAKG;IAEH,aALW,QAAQ,GAAC,QAAQ,GAAC,OAAO,GAAC,QAAQ,GAAC,MAAM,SACzC,KAAK,WACL,OAAO,OAKjB;IAED;;;OAGG;IACH,UAFW,MAAM,OAIhB;IAED,iBAEC;IAED,gBAEC;IAED,yBAEC;IAED,2BAEC;IAED,cAEC;IAED,0BAKC;IAED,0BAKC;IAED,eAEC;IAED;;;;OAIG;IACH,UAFW,MAAM,WAIhB;IAED;;;OAGG;IACH,eAFW,UAAU,WAIpB;IAED;;;;;;;OAOG;IACH,SAJW,MAAM,MAAO,OACb,MAAM,MAAO,YACb,OAAO,gBAuEjB;IA/CC,mBAAqB;IAGnB,yBAAiD;IAqBpB,QAAoC;IAI7C,4BAAuB;IAqB/C;;;;;OAKG;IACH,YAHW,MAAM,WACN,OAAO,gBAIjB;IAED;;;OAGG;IACH,eAFW,OAAO,gBAMjB;IAED;;;;OAIG;IACH,kBAFW,MAAM,OAKhB;IAED;;;;;;;;OAQG;IACH,kCAeC;IAED;;;;OAIG;IACH,gBAFW,MAAM,OAKhB;IAED;;;OAGG;IACH,0BAEC;IAED;;;;OAIG;IACH,eAFW,OAAO,OAgBjB;IAED;;;;;;;OAOG;IACH,UAJW,MAAM,QACN,MAAM,GAAC,OAAO,YACd,OAAO,OAiEjB;IAED;;;;;OAKG;IACH,kBAFW,OAAO,WA2BjB;IAED;;;;OAIG;IACH,WAKC;IAED;;;;;OAKG;IACH,YAHW,OAAO,YACP,OAAO,WAIjB;IAED;;OAEG;IACH,iBAEC;IAED;;;OAGG;IACH,kBAFW,OAAO,WAIjB;IAED;;;;;OAKG;IACH,iBAHW,UAAU,YACV,OAAO,WASjB;CACF"} \ No newline at end of file diff --git a/src/types/storage.d.ts b/src/types/storage.d.ts new file mode 100644 index 0000000..a39bb9b --- /dev/null +++ b/src/types/storage.d.ts @@ -0,0 +1,34 @@ +export default Storage; +declare class Storage { + constructor(id: any, type: any, batchedWrites?: boolean); + storeInitialized: Promise; + store: any; + name: any; + /** + * @param {'local'|'session'|'indexed'|'in_memory'} type + * @param {boolean} batchedWrites + */ + initStore(type: 'local' | 'session' | 'indexed' | 'in_memory', batchedWrites: boolean): Promise; + flush(): any; + clear(): Promise; + sync(): { + (method: any, model: any, options: any): Promise; + __name__: string; + }; + removeCollectionReference(model: any, collection: any): any; + addCollectionReference(model: any, collection: any): any; + getCollectionReferenceData(model: any): {}; + save(model: any): Promise; + create(model: any, options: any): Promise; + update(model: any): Promise; + find(model: any): any; + findAll(): Promise; + destroy(model: any, collection: any): Promise; + getStorageSize(): any; + getItemName(id: any): string; +} +declare namespace Storage { + export let sessionStorageInitialized: any; + export { localForage }; +} +//# sourceMappingURL=storage.d.ts.map \ No newline at end of file diff --git a/src/types/storage.d.ts.map b/src/types/storage.d.ts.map new file mode 100644 index 0000000..f2cd361 --- /dev/null +++ b/src/types/storage.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../storage.js"],"names":[],"mappings":";AAkBA;IACE,yDAgBC;IATG,gCAA2D;IAE3D,WAAiB;IAMnB,UAAc;IAGhB;;;OAGG;IACH,gBAHW,OAAO,GAAC,SAAS,GAAC,SAAS,GAAC,WAAW,iBACvC,OAAO,iBAgBjB;IAED,aAEC;IAED,uBAMC;IAED;;;MAiFC;IAED,4DAOC;IAED,yDAUC;IAED,2CAYC;IAED,+BAYC;IAED,+CASC;IAED,iCAEC;IAED,sBAEC;IAED,0BASC;IAED,mDAKC;IAED,sBAEC;IAED,6BAEC;CACF"} \ No newline at end of file diff --git a/src/types/utils/events.d.ts b/src/types/utils/events.d.ts new file mode 100644 index 0000000..308b14f --- /dev/null +++ b/src/types/utils/events.d.ts @@ -0,0 +1,28 @@ +/** + * Iterates over the standard `event, callback` (as well as the fancy multiple + * space-separated events `"change blur", callback` and jQuery-style event + * maps `{event: callback}`). + */ +export function eventsApi(iteratee: any, events: any, name: any, callback: any, opts: any): any; +export function onApi(events: any, name: any, callback: any, options: any): any; +/** + * An try-catch guarded #on function, to prevent poisoning the global + * `_listening` variable. + * @param {any} obj + * @param {string} name + * @param {Function} callback + * @param {any} context + */ +export function tryCatchOn(obj: any, name: string, callback: Function, context: any): any; +/** + * The reducing API that removes a callback from the `events` object. + */ +export function offApi(events: any, name: any, callback: any, options: any): any; +/** + * Reduces the event callbacks into a map of `{event: onceWrapper}`. + * `offer` unbinds the `onceWrapper` after it has been called. + */ +export function onceMap(map: any, name: any, callback: any, offer: any): any; +/** Handles triggering the appropriate event callbacks. */ +export function triggerApi(objEvents: any, name: any, callback: any, args: any): any; +//# sourceMappingURL=events.d.ts.map \ No newline at end of file diff --git a/src/types/utils/events.d.ts.map b/src/types/utils/events.d.ts.map new file mode 100644 index 0000000..6bfe66e --- /dev/null +++ b/src/types/utils/events.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../utils/events.js"],"names":[],"mappings":"AAMA;;;;GAIG;AACH,gGAmBC;AAGD,gFAWC;AAED;;;;;;;GAOG;AACH,gCALW,GAAG,QACH,MAAM,+BAEN,GAAG,OAQb;AAED;;GAEG;AACH,iFAkDC;AAED;;;GAGG;AACH,6EASC;AAED,0DAA0D;AAC1D,qFASC"} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index ccfefdb..3e3e15a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,8 +9,13 @@ "allowJs": true, "checkJs": true, + // Generate d.ts files + "declaration": true, + "emitDeclarationOnly": true, + "declarationMap": true, + "rootDir": "./src", - "outDir": "./types/", + "outDir": "./src/types/", "baseUrl": "./src/", "esModuleInterop": true,