Giter VIP home page Giter VIP logo

typesaurus's Introduction

🎉️ NEW: Typesaurus X is out!

🦕 Typesaurus

TypeScript-first ODM for Firestore.

Looking for React adaptor? Check Typesaurus React!

Why?

  • Designed with TypeScript's type inference in mind
  • Universal code (browser & Node.js)
  • Uncompromised type-safety
  • Code autocomplete
  • Say goodbye to any!
  • Say goodbye to exceptions!
  • Ready to start? Follow this guide.

Installation

The library is available as an npm package. To install Typesaurus, run:

npm install --save typesaurus firebase firebase-admin

Note that Typesaurus requires the firebase package to work in the web environment and firebase-admin to work in Node.js. These packages aren't listed as dependencies, so they won't install automatically with the Typesaurus package.

Features

  • Complete type-safety: uncompromised type-safety, includes Firestore quirks.
  • Universal package: reuse the same code on the client and server.
  • JavaScript-native: converts Firestore data types, i.e. timestamp, to native JS types, i.e. Date.
  • Build size-efficiency: optimized build-size for web.
  • Typed ids: all document ids are types, so you'll never mix up a user id with an account id.
  • Centralized schema: easy to define, read and update.
  • Single-import principle: single import to define, single import to use.

Changelog

See the changelog.

License

MIT © Sasha Koss

typesaurus's People

Contributors

denkigai avatar dependabot[bot] avatar edtsech avatar hotchpotch avatar justin-cheung avatar kossnocorp avatar mrdgh2821 avatar obusk avatar qs-f avatar reedom avatar swen128 avatar thomastoye avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

typesaurus's Issues

Async mode

Add submodule typesaurus/async that will enable the lazy loading of Firestore packages in the browser environment.

Nested Subcollections

In my project I'm trying to query a subcollection that itself lives on a subcollection. From what I see, this is currently not possible with Typesaurus, right? The subcollection() function only accepts root collections as a parameter. Are you planning to support such kind of data modeling?

By the way, if find this is a very neat project. I tried both https://github.com/lmcq/firebase-firestorm and https://github.com/wovalle/fireorm and switched to this now because it gives me the most flexibility and feature-completeness.

Have a great new year 2020! :)

onQueryMap that would allow combine nested onQuery

onQueryMap(
  rootNodesAccess,
  [untypedWhereArrayContains('memberIds', '420')],
  accessList => accessList.map(({ ref: { id } }),
  nodeId => onQuery(allNodes, [where('rootId', '==', nodeId)], nodes => /* process nodes */)
)

Where query key type problem

Hi! Thank you for creating Typesaurus - extremely helpful and I would like to use it all the way in our project.

I'm creating a following psuedo sample model samples.ts using 6.0.0 version:

import { collection } from 'typesaurus'

type Sample = {
    created: FirebaseFirestore.Timestamp,
    createdCount: number,
    problemKey: string,
    updated: FirebaseFirestore.Timestamp
};

export default collection<Sample>('samples');

Consuming as:

import { query, where } from 'typesaurus';
import samples from 'samples.ts';

const getSample: RequestHandler = async (req, res) => {
    const problemKeyTestValue = 'mochi';
    const sample = await query(samples, [where('problemKey', '===', problemKeyTestValue)]).then((sample) => {
        console.log('>>>', sample);
        return sample;
    });
};

But in return I get 'problemKey' with:

No overload matches this call.
  The last overload gave the following error.
    Argument of type '"problemKey"' is not assignable to parameter of type '["problemKey" | "created" | "createdCount" | "updated", "valueOf", never, string | number | symbol, string | number | symbol, string | number | symbol, string | number | symbol, string | ... 1 more ... | symbol, string | ... 1 more ... | symbol, string | ... 1 more ... | symbol]'.
index.d.ts(365, 18): The last overload is declared here.

I'm new to typescript and picking it up as I go. But it seems the compiler unable to resolve the type of problemKey:string to an array. I wonder if there's something wrong with the way I export/import the model. Any help is highly appreciated. Thank you!

realtime: to destroy /unsubscribe

Hi @kossnocorp, is there a way to unsubscribe from onQuery,onGet,onAll when certain query parameters are no longer available for e.g logged in user id (uid). If the realtime modules return a subscription, or promise that isn't a callback function like it currently is, it will be easy to unsubscribe.

Explicitly allow injection of `db` parameter

Right now, every read or write function imports firestore from the adaptors, but it would be very useful if these functions could have this db parameter optionally injected. A single program can have multiple Firebase apps initialized, each with their own database link.

Example:

// Below, the `db` parameter is optional but defaults otherwise to `firestore()`.
const userDoc = await get(ref(Users, 'user'), db)

Firestore GeoPoint support

The admin.firestore.GeoPoint class is returned for the geopoint type.

The wrapData function converts it to a plain object. e.g { _latitude: -1.323, _longitude: 23.5342 }.

I would at least prefer to see { latitude: -1.323, longitude: 23.5342 }. Though having access to the GeoPoint class as intended would also be nice.

Something like the following will be part of the change required:

} else if (data instanceof adaptor.consts.GeoPoint) {
  return data // what should we do here?
} 

How should typesaurus handle this type?

Reflect that updating a nested field using update function will overwrite it

As a StackOverflow comment states,

Given the initial value:

{
  "friends": {
    "friend-uid-1": true,
    "friend-uid-2": true
  }
}

Using set with merge:

db.collection('users')
  .doc('user-id')
  .set({ friends: { 'friend-uid-3': true } }, { merge: true })

Will produce:

{
  "friends": {
    "friend-uid-1": true,
    "friend-uid-2": true,
    "friend-uid-3": true
  }
}

While using update:

db.collection('users')
  .doc('user-id')
  .update({ friends: { 'friend-uid-3': true } })

Will overwrite the friends field:

{
  "friends": {
    "friend-uid-3": true
  }
}

However when updating with the dot notation (using field with Typesaurus):

db.collection('users')
  .doc('user-id')
  .update({ 'friends.friend-uid-3': true })

Will work similaraly to the set merge:

{
  "friends": {
    "friend-uid-1": true,
    "friend-uid-2": true,
    "friend-uid-3": true
  }
}

saving `serverTimestamp()` not working as expected

When using firebase.firestore.FieldValue.serverTimestamp(), the saved data results in:

image

I've tried saving this via set(doc, id, data) as well as db.doc(ref).set(data) using the same ref and data, and only the latter method saves in the appropriate format, ie:

image

Is there another way that the Firestore Timestamp must be generated for Typesaurus?

'ref(users).id' is throwing an error.

type User = { name: string }
const users = collection<User>('users')

const id = ref(users).id  **error here**
set(users, id, {name: 'John Doe'})

I can see that it says it will create an ID when one is not supplied. However, I can't get it to upload to google cloud functions without running into this error. Visual Studio is throwing an error too.

Expected 2 arguments, but got 1 .ts(2554)
index.d.ts(47, 3):  An argument for 'id' was not provided.

Doesn't seem to work with Parcel & rewrote my package.json

Getting this error and warnings when trying to add Typesaurus [1.12] to my project built with Parcel.

From Browser:

Error: ENOENT: no such file or directory, open '[..]\app\node_modules\typesaurus\remove\index.js'

After starting in terminal and seeing the following output:

parcel public/index.html

Server running at http://localhost:1234
‼ Could not load source file "../src/index.ts" in source map of "../node_modules/typesaurus/index.js".
‼ Could not load source file "../../src/cursor/index.ts" in source map of "../node_modules/typesaurus/cursor/index.js".
‼ Could not load source file "../../src/field/index.ts" in source map of "../node_modules/typesaurus/field/index.js".
‼ Could not load source file "../../src/collection/index.ts" in source map of "../node_modules/typesaurus/collection/index.js".
‼ Could not load source file "../../src/get/index.ts" in source map of "../node_modules/typesaurus/get/index.js".
‼ Could not load source file "../../src/limit/index.ts" in source map of "../node_modules/typesaurus/limit/index.js".
‼ Could not load source file "../../src/group/index.ts" in source map of "../node_modules/typesaurus/group/index.js".
‼ Could not load source file "../../src/ref/index.ts" in source map of "../node_modules/typesaurus/ref/index.js".
‼ Could not load source file "../../src/set/index.ts" in source map of "../node_modules/typesaurus/set/index.js".
‼ Could not load source file "../../src/where/index.ts" in source map of "../node_modules/typesaurus/where/index.js".
‼ Could not load source file "../../src/subcollection/index.ts" in source map of "../node_modules/typesaurus/subcollection/index.js".
‼ Could not load source file "../../src/update/index.ts" in source map of "../node_modules/typesaurus/update/index.js".
‼ Could not load source file "../../src/remove/index.ts" in source map of "../node_modules/typesaurus/remove/index.js".
‼ Could not load source file "../../src/batch/index.ts" in source map of "../node_modules/typesaurus/batch/index.js".
‼ Could not load source file "../../src/onQuery/index.ts" in source map of "../node_modules/typesaurus/onQuery/index.js".
‼ Could not load source file "../../src/query/index.ts" in source map of "../node_modules/typesaurus/query/index.js".
‼ Could not load source file "../../src/getMany/index.ts" in source map of "../node_modules/typesaurus/getMany/index.js".
‼ Could not load source file "../../src/value/index.ts" in source map of "../node_modules/typesaurus/value/index.js".
‼ Could not load source file "../../src/doc/index.ts" in source map of "../node_modules/typesaurus/doc/index.js".
‼ Could not load source file "../../src/transaction/index.ts" in source map of "../node_modules/typesaurus/transaction/index.js".
‼ Could not load source file "../../src/add/index.ts" in source map of "../node_modules/typesaurus/add/index.js".
‼ Could not load source file "../../src/data/index.ts" in source map of "../node_modules/typesaurus/data/index.js".
‼ Could not load source file "../../src/adaptor/browser.ts" in source map of "../node_modules/typesaurus/adapt‼ Could not load source file "../src/index.ts" in source map of "../node_modules/typesaurus/index.js".
‼ Could not load source file "../../src/cursor/index.ts" in source map of "../node_modules/typesaurus/cursor/index.js".
‼ Could not load source file "../../src/get/index.ts" in source map of "../node_modules/typesaurus/get/index.js".
‼ Could not load source file "../../src/collection/index.ts" in source map of "../node_modules/typesaurus/collection/index.js".
‼ Could not load source file "../../src/field/index.ts" in source map of "../node_modules/typesaurus/field/index.js".
‼ Could not load source file "../../src/limit/index.ts" in source map of "../node_modules/typesaurus/limit/index.js".
‼ Could not load source file "../../src/group/index.ts" in source map of "../node_modules/typesaurus/group/index.js".
‼ Could not load source file "../../src/where/index.ts" in source map of "../node_modules/typesaurus/where/index.js".
‼ Could not load source file "../../src/ref/index.ts" in source map of "../node_modules/typesaurus/ref/index.js".
‼ Could not load source file "../../src/set/index.ts" in source map of "../node_modules/typesaurus/set/index.js".
‼ Could not load source file "../../src/subcollection/index.ts" in source map of "../node_modules/typesaurus/subcollection/index.js".
‼ Could not load source file "../../src/update/index.ts" in source map of "../node_modules/typesaurus/update/index.js".
‼ Could not load source file "../../src/batch/index.ts" in source map of "../node_modules/typesaurus/batch/index.js".
‼ Could not load source file "../../src/remove/index.ts" in source map of "../node_modules/typesaurus/remove/index.js".
‼ Could not load source file "../../src/onQuery/index.ts" in source map of "../node_modules/typesaurus/onQuery/index.js".
‼ Could not load source file "../../src/value/index.ts" in source map of "../node_modules/typesaurus/value/index.js".
‼ Could not load source file "../../src/getMany/index.ts" in source map of "../node_modules/typesaurus/getMany/index.js".
‼ Could not load source file "../../src/doc/index.ts" in source map of "../node_modules/typesaurus/doc/index.js".
‼ Could not load source file "../../src/transaction/index.ts" in source map of "../node_modules/typesaurus/transaction/index.js".
‼ Could not load source file "../../src/add/index.ts" in source map of "../node_modules/typesaurus/add/index.js".
‼ Could not load source file "../../src/data/index.ts" in source map of "../node_modules/typesaurus/data/index.js".
‼ Could not load source file "../../src/query/index.ts" in source map of "../node_modules/typesaurus/query/index.js".
‼ Could not load source file "../../src/adaptor/utils.ts" in source map of "../node_modules/typesaurus/adaptor/utils.js".
npm WARN app No repository field.

Have not done much other than try to import the library, create a collection reference and add a document.

Also seeing a very odd side-effect, after getting this error my package.json file has been rewritten to contain only the following:

{
  "devDependencies": {
    "typescript": "^3.8.3"
  }
}

Would love to use this library if there is a solution. Maybe I just need to add a tsconfig flag or something?

Thanks, best.

want to have docChanges on onQuery etc.

For the client side performance improvement, I want to have "docChanges" on "onQuery" and other "on" series.
https://firebase.google.com/docs/firestore/query-data/listen#view_changes_between_snapshots

To achieve it, I think there are several API candidates while the docChanges should be supplied optionally for performance reasons.

  1. Introduce variant functions for each "on" series. E.g. onQueryWithDocChanges for onQuery
export default function onQueryWithDocChanges<Model>(
  collection: Collection<Model> | CollectionGroup<Model>,
  queries: Query<Model, keyof Model>[],
  onResult: (docs: Doc<Model>[], docChanges: DocChange<Model>[]),
  onError?: (err: Error) => any
): () => void {
  1. Add an options specification argument to let clients specify their requirement
export default function onQuery<Model>(
  collection: Collection<Model> | CollectionGroup<Model>,
  queries: Query<Model, keyof Model>[],
  onResult: (docs: Doc<Model>[], extra?: { docChanges?: DocChange<Model>[] }),
  onError?: (err: Error) => any,
  options?: { docChanges?: boolean }
): () => void {
  1. Add an "getter" to onResult's argument
export default function onQuery<Model>(
  collection: Collection<Model> | CollectionGroup<Model>,
  queries: Query<Model, keyof Model>[],
  onResult: (docs: Doc<Model>[], getDocChanges: () => DocChange<Model>[]) => any,
  onError?: (err: Error) => any
): () => void {

A sample implementation to the 3rd.
https://github.com/kossnocorp/typesaurus/compare/master...reedom:feature/docchanges?expand=1
But as reviewing Firebase.QuerySnapshot now again, chances are that someone might want to get readTime.
So, the 2nd would be better while it's expandable.

How to query by FieldPath.documentId()?

Is there equivalent feature of FieldPath.documentId()?

I was tried to query "documentId-starts with",
if there was the one, it'd look like:

query(items, [
  where(documentId(), ">=", "abc"),
  where(documentId(), "<", "abd")
])

Firebase Functions

Firebase Functions adapter, firebase functions does not requires to configure the app.

but instead of firebase-admin package, it is likely to use firebase-functions.

Add note about using with Next.js

At the moment the only option to make Typesaurus work with Next.js is to add this command to package.json:

"postinstall": "echo '{\"main\":\"./browser/index\"}' > node_modules/typesaurus/adaptor/package.json"

See for more info: #49

How to update nested maps

I am trying to update a nested map. In Firestore SDK you would do

// Firestore data:
{
first: {
    test: aaaaa,
    test2: cccc
    }
}

// Firestore SDK
var setAda = dbFirestore.collection('users').doc('alovelace').update({
    "first.test": "12345"
});

(See this answer: https://stackoverflow.com/a/49151326/9642772)

How would I do with typesaurus?

I'm pretty sure this I should be using Fields. However, I can't figure out the exact syntax. Any help would be appreciated.

Transaction API features

Hi there (and sorry for creating all the issues)!

I noticed that the transaction API in typesaurus doesn't support querying within a transaction. In the types for Firestore, they allow transaction.get to take a query object (and acquire pessimistic locks on all the returned documents).

Adding query to the transaction API seems straightforward enough; is this something that could be added in the near-term?

Also, please let me know if I could help out with this task.

Unexpected token *

Get the following error when trying to use typesaurus with google cloud functions:

Detailed stack trace: /srv/node_modules/@google-cloud/firestore/build/src/collection-group.js:55
async *getPartitions(desiredPartitionCount) {
^

SyntaxError: Unexpected token *
at createScript (vm.js:80:10)
at Object.runInThisContext (vm.js:139:10)
at Module._compile (module.js:617:28)
at Object.Module._extensions..js (module.js:664:10)
at Module.load (module.js:566:32)
at tryModuleLoad (module.js:506:12)
at Function.Module._load (module.js:498:3)
at Module.require (module.js:597:17)
at require (internal/module.js:11:18)
at Object. (/srv/node_modules/@google-cloud/firestore/build/src/index.js:39:28).

The offending code:

import * as t from 'typesaurus'
...
interface User {
	userId?     : string;
	email?       :	string;
	phone?      :	string;
}
// -- or --
 type User = {
        userId?     : string; 
        email? 		  :	string;
        phone?      :	string;
}
...
firebase.initializeApp(firebaseConfig)
const users = t.collection<user.User>('users');

Does anyone know what the cause of this could be?
Thanks

Eliminate need for firebase-admin when building web-only spa

Developing a SPA with vue.js, and added typesaurus for data access. Now on build, when running vue-cli-service build I get the error "Cannot find module 'firebase-admin' or its corresponding type declaration". I do have all needed for browser, but don't want to import admin code to keep attack surface smaller in terms of security.

$ vue-cli-service build

\  Building for production...Starting type checking service...
Using 1 worker with 2048MB memory limit
|  Building for production...

 ERROR  Failed to compile with 1 errors                                                                                                                                      3:40:43 PM

 error  in C:/Users/jcmen/development/ng-dashts/node_modules/typesaurus/adaptor/node.d.ts

ERROR in C:/Users/jcmen/development/ng-dashts/node_modules/typesaurus/adaptor/node.d.ts(5,24):
5:24 Cannot find module 'firebase-admin' or its corresponding type declarations.
    3 |  */
    4 | import * as firestore from '@google-cloud/firestore'
  > 5 | import * as admin from 'firebase-admin'
      |                        ^
    6 | export declare type Adaptor = {
    7 |   firestore: admin.firestore.Firestore
    8 |   consts: AdaptorConsts

 ERROR  Build failed with errors.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Is there a way to do the imports in a way to avoid the node adapter being transpiled?

Simple pagination with offset

Could not find it in the documentation, but would be great if we could use offset() instead of startAfter / startBefore etc for paginating documents.

Example from my firestore query:

let page = Number(req.query.page);
let limit = Number(req.query.limit);

// Calculate offset based on page and limit
let offset = limit * (page - 1);

let query = firestore()
      .collection("users")
      .orderBy("createdAt", "desc")
      .offset(offset)
      .limit(limit);

Passing SnapshotOptions.

I'd like to be able to pass or set somehow SnapshotOptions.

These can be useful when using serverTimestamps, where you can tell Firebase to use the previous value or an estimate instead of null while a write is pending.

This is passed as data = documentSnapshot.data({serverTimestamps: 'estimate'}).

https://firebase.google.com/docs/reference/js/firebase.firestore.SnapshotOptions (though the docs on this say nothing of usage).

See https://github.com/firebase/firebase-js-sdk/blob/master/packages/firestore-types/index.d.ts (ctr+f "SnapshotOptions")

I've been digging around slightly, seems like this could be done by adding it as an optional parameter in each of the getting functions (get, all, etc), and also in typesaurus-react.

As far as I can tell, SnapshotOptions is only a thing in the browser sdk, not in the nodejs sdk. I'm not sure how to handle that.

Work with Gatsby (on node without firebase-admin)

I'm having issues building a Gatsby site with typesaurus.
I don't actually use typesaurus while doing SSR, only on the client.

The issue is that if I don't have firebase-admin installed while doing SSR webpack will have an issue because it cannot find firebase-admin.

If I install it webpack will complain about not being able to process some ".proto" files.

I was able to fix it by patching the built node.js adaptor to be the same as the browser but it cannot export FirestoreDocumentReference, FirestoreTimestamp and FirestoreFieldValue or it will error:

 WebpackError: TypeError: Cannot read property 'DocumentReference' of undefined
// typesaurus/adaptor/node.js that works with gatsby
// Its a copy of /adaptor/browser.js with some stuff comented out (see at the bottom)
'use strict'
/**
 * Browser Firestore adaptor.
 */
var __importStar =
  (this && this.__importStar) ||
  function(mod) {
    if (mod && mod.__esModule) return mod
    var result = {}
    if (mod != null)
      for (var k in mod)
        if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]
    result['default'] = mod
    return result
  }
Object.defineProperty(exports, '__esModule', { value: true })
const firebase = __importStar(require('firebase/app'))
require('firebase/firestore')
function store() {
  const firestore = firebase.firestore()
  // At the moment, the browser's Firestore adaptor doesn't support getAll.
  // Get rid of the fallback when the issue is closed:
  // https://github.com/firebase/firebase-js-sdk/issues/1176
  if (!('getAll' in firestore)) return Object.assign(firestore, { getAll })
  return firestore
}
exports.default = store
function getAll(...docs) {
  return Promise.all(docs.map(doc => doc.get()))
}
// exports.FirestoreDocumentReference = firebase.firestore.DocumentReference <-- comment this out
// exports.FirestoreTimestamp = firebase.firestore.Timestamp <-- comment this out
// exports.FirestoreFieldValue = firebase.firestore.FieldValue <-- comment this out
//# sourceMappingURL=browser.js.map

if I could just pass the database instance (as proposed on #7) and these lines I commented out were lazy getters the problem would kind of go away.

I tried a couple of things on my fork but the only fix would be to export "typesaurus-gatsby" where both adaptors use firebase-admin.

Add find method

A method that returns the first element in the query and overrides the limit query.

getDocParentId?

It seems like it would be very helpful for working with subcollections if there was a function in the API to fetch the parent ID of a document, unless there is already some easier way to do this that I am not aware of yet.

Thank you!

How to use `firebase` package in NodeJS?

I use typesaurus with Next.js that is working on NodeJS and browser.

When typesaurus use with Next.js, require firebase-admin.
I want to use only firebase package.

Do you know how to use firebase package in NodeJS (or Next.js)?

How to use with "FieldValue.increment" etc.

I have a number field, and I would like to increment it with FieldValue.increment. However, doing so causes a type error. To fix the type error, I cast the FieldValue as unknown as number

{
    key: (admin.firestore.FieldValue.increment(
            <value to increment by>
          ) as unknown) as number
}

However, in Firestore, the value gets converted into a map with a key of operand

Firestore document:

{
    key: {
        operand: <value to increment by>
    }
}

Any suggestions?

Is it possible to inject react native firebase ataptor?

I've tried to check adaptor module, but it seems adaptors for browser and node are hardcoded there. Even if I can inject adaptor into node adaptor, the one from google is still imported there so I'd have to have it installed in my react native project.

React Native Firebase is trying to have the same JS API as browser one

import firestore from '@react-native-firebase/firestore';

// Get user document with an ID of ABC
const userDocument = firestore()
  .collection('Users')
  .doc('ABC');

https://rnfirebase.io/firestore/usage

Deeply Nested Subcollections

It looks like a new approach for handling nested subcollections has been implemented since #12, however it still only seems to be working with subcollections nested one level deep. When I try to declare a subcollection of a subcollection of a subcollection, such as:

const courses = collection<Course>('courses')
const levels = subcollection<Level, Course>( 'levels', courses )
const pages = subcollection<Page, Level, Course>( 'pages', levels )
const media = subcollection<Media, Page, Level, Course>( 'media', pages )

This works until the last level, where I get the following error from the compiler:
Type 'Course' does not satisfy the constraint '[string, string, string, string]'.ts(2344)

Thank you!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.