FirelordJS

🔥High Precision Typescript Wrapper for Firestore Web, Providing Unparalleled Type Safe and Dev Experience

MIT License

Downloads
1.2K
Stars
84
Committers
5
FirelordJS - 2.6.5

Published by tylim88 about 1 year ago

  1. improve collection JSDoc
	/**
	 * Gets a {@link CollectionReference} instance that refers to the collection at
	 * the specified absolute path.
	 *
	 *  related documentations:
	 *  - {@link https://firelordjs.com/guides/metatype child meta type}
	 *  - {@link https://firelordjs.com/quick_start#operations operation}
	 * @param documentIds
	 *  All the docID(s) needed to build this document path, eg
	 *  - for top-collection: example.collection()
	 *  - for sub-collection: example.collection(GrandParentDocId, ParentsDocId)
	 *
	 * @returns The {@link CollectionReference} instance.
	 */
  1. improve collectionGroup JSDoc
	/**
	 *  related documentations:
	 *  - {@link https://firelordjs.com/quick_start/#query query}
	 *  - {@link https://firelordjs.com/quick_start/#onsnapshot onSnapshot}
	 * @returns — The created {@link Query}.
	 */
FirelordJS - 2.6.4

Published by tylim88 about 1 year ago

expose types Unsubscribe and OnSnapshot

FirelordJS - 2.6.3

Published by tylim88 over 1 year ago

  1. better onSnapshot JSDoc
    /**
     * listen to filtered collection, entire collection or single document
     *
     * Attaches a listener for {@link DocumentSnapshot} Or {@link QuerySnapshot} events. You may either pass
     * individual {@link onNext} and {@link onError} callbacks. The listener can be cancelled by
     * calling the function that is returned when {@link OnSnapshot} is called.
     *
     * related documentation:
     *  - {@link https://firelordjs.com/quick_start#onsnapshot}
     *
     * @param reference
     *
     * Type 1: {@link Query} eg: query(example.collection(...), ...) listen to filtered collection
     *
     * Type 2: CollectionGroup({@link Query}) eg: query(example.collectionGroup(...), ...) listen to filtered {@link Query}
     *
     * Type 3: {@link CollectionReference} eg: example.collection(...) listen to entire collection
     *
     * Type 4: CollectionGroup({@link Query}) reference eg: example.collectionGroup(...) listen to entire {@link Query}
     *
     * Type 5: {@link DocumentReference} eg: example.doc(...) listen to a single document
     * @param onNext - A callback to be called every time a new {@link DocumentSnapshot} or {@link QuerySnapshot} is available.
     *
     * Type 1: receive {@link DocumentSnapshot} if {@link reference} is {@link DocumentReference} eg: (value: {@link DocumentSnapshot}) => { handle data here }
     *
     * Type 2: receive {@link QuerySnapshot} if {@link reference} is CollectionGroup or {@link Query} or {@link CollectionReference} eg: (value: {@link QuerySnapshot}) => { handle data here }
     *
     * @param onError - optional parameter.
     *
     * Type 1: a callback to be called if the listen fails or is cancelled. No further callbacks will occur. Eg: (error: {@link FirestoreError})=> { handle error here}
     *
     * Type 2: {@link SnapshotListenOptions} eg: { includeMetadataChanges: boolean }
     * @param options - optional parameter. If {@link onError} is {@link SnapshotListenOptions} eg: { includeMetadataChanges: boolean }, then this argument is never. Else it is {@link SnapshotListenOptions} eg: { includeMetadataChanges: boolean }
     * @returns An unsubscribe function that can be called to cancel
     * the snapshot listener.
     */
  1. remove onSnapshot overloading
  2. fix onSnapshot unable to infer type from collection reference
FirelordJS - 2.6.2

Published by tylim88 over 1 year ago

Object unions type was banned before v2.6.2 because it brings uncertainty that cannot be handled reasonably. For example, with {a:number}|{b:string}, you can set {a:1} then update {b:"x"}, in this case the type is no longer unions type but an intersection type: {a:number} & {b:string}. The reason I decided to lift the limitation is that I believe we should value functionalities over less practical strict typing. Plus in future update operation Mandatory Field could mitigate this problem.

FirelordJS - 2.6.1

Published by tylim88 over 1 year ago

  1. improve doc ref JSDoc, this is what user will see
    /**
     * Gets a `DocumentReference` instance that refers to the document at the
     * specified absolute path.
     *
     * @param documentIds_or_CollectionReference
     * Option 1: all the docID(s) needed to build this document path, eg
     *  - for top-collection: example.doc(SelfDocId)
     *  - for sub-collection: example.doc(GrandParentDocId, ParentsDocId, SelfDocId).
     *
     * Option 2: CollectionReference (to create auto id doc ref), eg
     *  - for top-collection: example.doc(example.collection())
     *  - for sub-collection: example.doc(example.collection(GrandParentCollectionID, ParenCollectionID))
     *
     *
     *  documentation:
     *  {@link https://firelordjs.com/guides/metatype child meta type}
     *  {@link https://firelordjs.com/quick_start#operations operation}
     * @returns The `DocumentReference` instance.
     */
  1. doc ref no longer overload function (function overloading is very messy in type hint) and use union instead
  2. suggesting turn off some eslint rules in readme because of false errors
{
	"rules": {
		"@typescript-eslint/no-unsafe-assignment": "off",
		"@typescript-eslint/no-unsafe-call": "off",
		"@typescript-eslint/no-redundant-type-constituents": "off",
		"@typescript-eslint/no-unsafe-return": "off",
		"@typescript-eslint/no-unsafe-member-access": "off"
	}
}

v2.6 will focus on improving JSDoc

FirelordJS - 2.6.0

Published by tylim88 over 1 year ago

(Web only)

  1. update peer dependency firebase to v10.0.0
  2. remove the rule Error: You can't order your query by a field included in an equality '==' or 'in' clause. Exceptions to this rule are order by '__name__' or 'documentId()' because firebase v10.0.0 removed this limitation. I think dev exp is better with this rule but the removal is harmless,

side note: If you are using @firebase/rules-unit-testing for testing, you have to use @firebase/rules-unit-testing v3. Firebase v10 does not work with v2 (peer dependency issue)

FirelordJS - 2.5.20

Published by tylim88 over 1 year ago

make getFirelord tree shakable

https://firelordjs.com/guides/tree_shaking_getFirelord

const getFirelord = getFirelordShakable({
    // all properties are optional
    // choose what to keep
    orCreator,
    andCreator,
    docCreator,
    collectionCreator,
    collectionGroupCreator,
})

const example = getFirelord<Example>(db, 'someCollectionId')
FirelordJS - 2.5.13, 2.5.14, 2.5.15

Published by tylim88 over 1 year ago

  1. add more in code documentation

internal:

  1. fill virtual types so they resemble the type of possible values at runtime (virtual type is type that exist just to make typing easier, it does not resemble the possible values at runtime), This update will not breaks your code unless you were trying to access undocumented API.
  2. lots of housekeeping and refactoring
  3. fix emulator not working properly
  4. replace documentId() in test with __name__
FirelordJS - 2.5.11

Published by tylim88 over 1 year ago

  1. Firestore need time to resolve sever time stamp, so it is possible to retrieve a null value if we read the value immediately after we write it. However this is a very rare case, for smoother coding experience, I decided not to union Server Timestamp read type(Timestamp) with null anymore. User can choose to union ServerTimestamp with null in Meta Type to deal with edge case. This change does not break existing code.
  2. (internal) remove unionReadTimestampWithNull
FirelordJS - 2.5.10

Published by tylim88 over 1 year ago

  1. support Record<string, something> data type
  2. new APIs: transaction.updateNoFlatten, batch.updateNoFlatten, and updateDocNoFlatten.

for more details see https://github.com/tylim88/Firelord/releases/tag/2.4.16

FirelordJS - 2.5.9

Published by tylim88 over 1 year ago

  • temporary disable You can use at most one array-contains or array-contains-any clause per query. You can't combine array-contains with array-contains-any

this is because or query allows multiple array-contains or array-contains-any clauses but and query does not throw runtime error:

or(where('a', 'array-contains-any', ['2']),where('a', 'array-contains', '1'))

will throw runtime error error:

and(where('a', 'array-contains-any', ['2']),where('a', 'array-contains', '1'))

Solution exist but because of composite query nesting, it is going to be very complicated

I decided not to works on this for now, plus I am sick due to dengue

FirelordJS - 2.5.8

Published by tylim88 over 1 year ago

-if there is only one clause in or() query, will NOT throw Error: You cannot use 'not-in' in 'or' query, nested or not. But can be neighbor in 'and' query , eg: and(where('a','not-in',[1]), or(where('b','>',2), where('c','<',1))) type error

or(where('...', 'not-in', ['...'])) //will not throw
or(where('...', 'not-in', ['...']), where('...', '...', '...')) // will throw the type error
FirelordJS - 2.5.6

Published by tylim88 over 1 year ago

-(internal)remove AddSentinelFieldPathToCompare, RemoveSentinelFieldPathFromCompare and AddSentinelFieldPathToCompareHighLevel

They were poorly designed and have been replaced by a simpler solution. The type AddSentinelFieldPathToCompare will no longer appear in error messages

FirelordJS - 2.5.5

Published by tylim88 over 1 year ago

  1. documentId() now return 'name', this is to simplify the typing logic. documentId field value is probably meaningless right now as we could just use __name__, but will keep it for backward compatibility

  2. fix when orderby documentId, the cursor require full document path regardless of whether the reference is collection reference or collection group reference.

old behavior

query(colRef, orderBy(documentId()), endAt('abc')) // error: require full document path, eg 'a/b', reject plain document id <--incorrect behavior
query(colGroupRef, orderBy(documentId()), endAt('a/b') // ok, accept full document path and reject plain document id

new behavior

query(colRef, orderBy(documentId()), endAt('abc')) // ok, now need only plain document id and reject full path
query(colGroupRef, orderBy(documentId()), endAt('a/b') // ok, accept full document path and reject plain document id

the logic behind these type rules:

  1. collection reference require only plain document id,
  2. collection group reference require full document path
FirelordJS - 2.5.4

Published by tylim88 over 1 year ago

-update an error message
-fix where clause return non-descriptive never error on incorrect field path type, example

the bug:
image

now work as expected
image

FirelordJS - 2.5.2 and 2.5.3

Published by tylim88 over 1 year ago

2.5.2

2.5.3

  • fix, when filtering by document id and the value type is string, throw error even though document id type is string

previously query(collectionRef, where(documentId(), '!=', 'a' as string)) always error, now only throw if document id type is string literal(not wide type string)

FirelordJS - 2.5.0

Published by tylim88 over 1 year ago

  • No longer stopping you from using __name__ for filter field path, eg: where('__name__', '==', 'something') is now error free
  • you can now use documentId() for orderBy field, orderBy(documentId()) is now error free

summary: with these 2 changes, you can use both documentId() and __name__ for orderBy and where clause

  • update You can't order your query by a field included in an equality (==) or (in) clause ruling: query(ref, orderBy(x), where(x, '==', 'something')) is now error free, where x is documentId() or __name__. This is a special case.

  • tons of housekeeping, refactoring and improvements

New Feature: Composite Rulings

mirror API of Firestore or & and query

query(
	example.collection(),
	example.or(
		where('f.h', '>', 2929),
		where('a', '==', 1),
		// you can nest composite query https://firebase.google.com/docs/firestore/query-data/queries#disjunctive_normal_form
		example.and(
			where('f.g', 'in', [new Date(999), new Date(3000)]),
			where('b.d', 'array-contains', { e: 'a' })
		)
	)
)

nested composite rulings are ready, example:

image

It has all the normal query rulings plus new rulings specified to composite query.

This was very difficult to create. I had to leave out many details in this release note due to the large number of changes.

FirelordJS - 2.4.8

Published by tylim88 over 1 year ago

  • please update firebase to v9.18 +
  • (query) enable more than one in combination, this was not possible before v9.17.2
query(ref, where('a', 'in', [1]), where('b', 'in', [2])) // now it is possible!
query(ref, where('a', 'in', [1]), where('b', 'array-contains-any', [2])) // now it is possible!

these updates do not apply to admin as admin haven't catch up to web 9.17.2

FirelordJS - 2.4.7

Published by tylim88 over 1 year ago

This patch consist of 2 important changes and 1 important fix:

changes:

  1. Greatly simplify MetaTypeCreator, improving performance
  2. introduce new type transformation: WriteMerge type, dedicated type for set merge operation

fix:

  1. fix DeleteField type transformation

the old DeleteField is incorrectly being treated as object and will be replaced by error message when we union it with another object

in 2.4.7, DeleteField is no longer treated as object

this is not a breaking change, it opens up a new possibility

Old DeleteField Type Transformation

type ErrorUnionInvolveObjectType =
	'Error: Please check your type declaration, do not union object literal type with other type except PossiblyReadAsUndefined'

type A = MetaTypeCreator<
	{
		b: {
			d: { e: false } | DeleteField
		}
	},
	'A'
>
type Read = {
	b: {
		d: ErrorUnionInvolveObjectType
	}
}

type Write = {
	b: {
		d: ErrorUnionInvolveObjectType
	}
}

type WriteFlatten = {
	b: {
		d: ErrorUnionInvolveObjectType
	}
	'b.d': ErrorUnionInvolveObjectType
}

type Compare = {
	b: {
		d: ErrorUnionInvolveObjectType
	}
	'b.d': ErrorUnionInvolveObjectType
}

New DeleteField Type Transformation:

type A = MetaTypeCreator<
	{
		b: {
			d: { e: false } | DeleteField
		}
	},
	'A'
>
type Read = {
	b: {
		d: { e: false } | undefined
	}
}

type Write = {
	b: {
		d: { e: false }
	}
}

type WriteMerge = { // new type!
	b: {
		d: { e: false } | DeleteField
	}
}

type WriteFlatten = {
	b: {
		d: { e: false } | DeleteField
		'd.e': false
	}
	'b.d': { e: false } | DeleteField
	'b.d.e': false
}

type Compare = {
	b: {
		d: { e: false }
		'd.e': false
	}
	'b.d': { e: false }
	'b.d.e': false
}
FirelordJS - 2.4.0

Published by tylim88 over 1 year ago

strongly recommend upgrade to v2.4 to enjoy performance improvement from TS v5

Package Rankings
Top 6.7% on Proxy.golang.org
Top 5.58% on Npmjs.org
Related Projects