mirror of
https://github.com/aspnet/JavaScriptServices.git
synced 2025-12-22 17:47:53 +00:00
Merge domain-task repo into this one
This commit is contained in:
@@ -1,10 +0,0 @@
|
|||||||
// TODO: Move this on to definitelytyped, and take a dependency on whatwg-fetch
|
|
||||||
// so that the 'fetch' function can have the correct type args
|
|
||||||
|
|
||||||
declare module 'domain-task' {
|
|
||||||
function addTask(task: PromiseLike<any>): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare module 'domain-task/fetch' {
|
|
||||||
function fetch(url, options?): Promise<any>;
|
|
||||||
}
|
|
||||||
@@ -37,6 +37,9 @@
|
|||||||
},
|
},
|
||||||
"redux-thunk/redux-thunk.d.ts": {
|
"redux-thunk/redux-thunk.d.ts": {
|
||||||
"commit": "e69fe60f2d6377ea4fae539493997b098f52cad1"
|
"commit": "e69fe60f2d6377ea4fae539493997b098f52cad1"
|
||||||
|
},
|
||||||
|
"whatwg-fetch/whatwg-fetch.d.ts": {
|
||||||
|
"commit": "f4b1797c1201b6c575668f5d7ea12d9b1ab21846"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1
samples/react/MusicStore/typings/tsd.d.ts
vendored
1
samples/react/MusicStore/typings/tsd.d.ts
vendored
@@ -9,3 +9,4 @@
|
|||||||
/// <reference path="react-router-bootstrap/react-router-bootstrap.d.ts" />
|
/// <reference path="react-router-bootstrap/react-router-bootstrap.d.ts" />
|
||||||
/// <reference path="react-router-redux/react-router-redux.d.ts" />
|
/// <reference path="react-router-redux/react-router-redux.d.ts" />
|
||||||
/// <reference path="redux-thunk/redux-thunk.d.ts" />
|
/// <reference path="redux-thunk/redux-thunk.d.ts" />
|
||||||
|
/// <reference path="whatwg-fetch/whatwg-fetch.d.ts" />
|
||||||
|
|||||||
85
samples/react/MusicStore/typings/whatwg-fetch/whatwg-fetch.d.ts
vendored
Normal file
85
samples/react/MusicStore/typings/whatwg-fetch/whatwg-fetch.d.ts
vendored
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
// Type definitions for fetch API
|
||||||
|
// Project: https://github.com/github/fetch
|
||||||
|
// Definitions by: Ryan Graham <https://github.com/ryan-codingintrigue>
|
||||||
|
// Definitions: https://github.com/borisyankov/DefinitelyTyped
|
||||||
|
|
||||||
|
declare class Request extends Body {
|
||||||
|
constructor(input: string|Request, init?:RequestInit);
|
||||||
|
method: string;
|
||||||
|
url: string;
|
||||||
|
headers: Headers;
|
||||||
|
context: string|RequestContext;
|
||||||
|
referrer: string;
|
||||||
|
mode: string|RequestMode;
|
||||||
|
credentials: string|RequestCredentials;
|
||||||
|
cache: string|RequestCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RequestInit {
|
||||||
|
method?: string;
|
||||||
|
headers?: HeaderInit|{ [index: string]: string };
|
||||||
|
body?: BodyInit;
|
||||||
|
mode?: string|RequestMode;
|
||||||
|
credentials?: string|RequestCredentials;
|
||||||
|
cache?: string|RequestCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare enum RequestContext {
|
||||||
|
"audio", "beacon", "cspreport", "download", "embed", "eventsource", "favicon", "fetch",
|
||||||
|
"font", "form", "frame", "hyperlink", "iframe", "image", "imageset", "import",
|
||||||
|
"internal", "location", "manifest", "object", "ping", "plugin", "prefetch", "script",
|
||||||
|
"serviceworker", "sharedworker", "subresource", "style", "track", "video", "worker",
|
||||||
|
"xmlhttprequest", "xslt"
|
||||||
|
}
|
||||||
|
declare enum RequestMode { "same-origin", "no-cors", "cors" }
|
||||||
|
declare enum RequestCredentials { "omit", "same-origin", "include" }
|
||||||
|
declare enum RequestCache { "default", "no-store", "reload", "no-cache", "force-cache", "only-if-cached" }
|
||||||
|
|
||||||
|
declare class Headers {
|
||||||
|
append(name: string, value: string): void;
|
||||||
|
delete(name: string):void;
|
||||||
|
get(name: string): string;
|
||||||
|
getAll(name: string): Array<string>;
|
||||||
|
has(name: string): boolean;
|
||||||
|
set(name: string, value: string): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare class Body {
|
||||||
|
bodyUsed: boolean;
|
||||||
|
arrayBuffer(): Promise<ArrayBuffer>;
|
||||||
|
blob(): Promise<Blob>;
|
||||||
|
formData(): Promise<FormData>;
|
||||||
|
json(): Promise<any>;
|
||||||
|
json<T>(): Promise<T>;
|
||||||
|
text(): Promise<string>;
|
||||||
|
}
|
||||||
|
declare class Response extends Body {
|
||||||
|
constructor(body?: BodyInit, init?: ResponseInit);
|
||||||
|
error(): Response;
|
||||||
|
redirect(url: string, status: number): Response;
|
||||||
|
type: string|ResponseType;
|
||||||
|
url: string;
|
||||||
|
status: number;
|
||||||
|
ok: boolean;
|
||||||
|
statusText: string;
|
||||||
|
headers: Headers;
|
||||||
|
clone(): Response;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare enum ResponseType { "basic", "cors", "default", "error", "opaque" }
|
||||||
|
|
||||||
|
interface ResponseInit {
|
||||||
|
status: number;
|
||||||
|
statusText?: string;
|
||||||
|
headers?: HeaderInit;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare type HeaderInit = Headers|Array<string>;
|
||||||
|
declare type BodyInit = Blob|FormData|string;
|
||||||
|
declare type RequestInfo = Request|string;
|
||||||
|
|
||||||
|
interface Window {
|
||||||
|
fetch(url: string|Request, init?: RequestInit): Promise<Response>;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare var fetch: typeof window.fetch;
|
||||||
4
src/Microsoft.AspNet.SpaServices/npm/domain-task/.gitignore
vendored
Normal file
4
src/Microsoft.AspNet.SpaServices/npm/domain-task/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
/typings/
|
||||||
|
/node_modules/
|
||||||
|
/*.js
|
||||||
|
/*.d.ts
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
!/*.js
|
||||||
|
!/*.d.ts
|
||||||
|
/typings/
|
||||||
12
src/Microsoft.AspNet.SpaServices/npm/domain-task/LICENSE.txt
Normal file
12
src/Microsoft.AspNet.SpaServices/npm/domain-task/LICENSE.txt
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
||||||
|
these files except in compliance with the License. You may obtain a copy of the
|
||||||
|
License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software distributed
|
||||||
|
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
|
CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
|
specific language governing permissions and limitations under the License.
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
TODO
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"name": "domain-task",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Tracks outstanding operations for a logical thread of execution",
|
||||||
|
"main": "main.js",
|
||||||
|
"scripts": {
|
||||||
|
"prepublish": "tsd update && tsc && echo 'Finished building NPM package \"domain-task\"'",
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"author": "Microsoft",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"domain-context": "^0.5.1",
|
||||||
|
"isomorphic-fetch": "^2.2.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
9
src/Microsoft.AspNet.SpaServices/npm/domain-task/src/domain-context.d.ts
vendored
Normal file
9
src/Microsoft.AspNet.SpaServices/npm/domain-task/src/domain-context.d.ts
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
declare module 'domain' {
|
||||||
|
var active: Domain;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module 'domain-context' {
|
||||||
|
function get(key: string): any;
|
||||||
|
function set(key: string, value: any): void;
|
||||||
|
function runInNewDomain(code: () => void): void;
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
import * as url from 'url';
|
||||||
|
import * as domain from 'domain';
|
||||||
|
import * as domainContext from 'domain-context';
|
||||||
|
import { addTask } from './main';
|
||||||
|
const isomorphicFetch = require('isomorphic-fetch');
|
||||||
|
const isBrowser: boolean = (new Function('try { return this === window; } catch (e) { return false; }'))();
|
||||||
|
|
||||||
|
// Not using a symbol, because this may need to run in a version of Node.js that doesn't support them
|
||||||
|
const domainTaskStateKey = '__DOMAIN_TASK_INTERNAL_FETCH_BASEURL__DO_NOT_REFERENCE_THIS__';
|
||||||
|
let noDomainBaseUrl: string;
|
||||||
|
|
||||||
|
function issueRequest(baseUrl: string, req: string | Request, init?: RequestInit): Promise<any> {
|
||||||
|
// Resolve relative URLs
|
||||||
|
if (baseUrl) {
|
||||||
|
if (req instanceof Request) {
|
||||||
|
const reqAsRequest = req as Request;
|
||||||
|
reqAsRequest.url = url.resolve(baseUrl, reqAsRequest.url);
|
||||||
|
} else {
|
||||||
|
req = url.resolve(baseUrl, req as string);
|
||||||
|
}
|
||||||
|
} else if (!isBrowser) {
|
||||||
|
// TODO: Consider only throwing if it's a relative URL, since absolute ones would work fine
|
||||||
|
throw new Error(`
|
||||||
|
When running outside the browser (e.g., in Node.js), you must specify a base URL
|
||||||
|
before invoking domain-task's 'fetch' wrapper.
|
||||||
|
Example:
|
||||||
|
import { baseUrl } from 'domain-task/fetch';
|
||||||
|
baseUrl('http://example.com'); // Relative URLs will be resolved against this
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Currently, some part of ASP.NET (perhaps just Kestrel on Mac - unconfirmed) doesn't complete
|
||||||
|
// its responses if we send 'Connection: close', which is the default. So if no 'Connection' header
|
||||||
|
// has been specified explicitly, use 'Connection: keep-alive'.
|
||||||
|
init = init || {};
|
||||||
|
init.headers = init.headers || {};
|
||||||
|
if (!init.headers['Connection']) {
|
||||||
|
init.headers['Connection'] = 'keep-alive';
|
||||||
|
}
|
||||||
|
|
||||||
|
return isomorphicFetch(req, init);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function fetch(url: string | Request, init?: RequestInit): Promise<any> {
|
||||||
|
const promise = issueRequest(baseUrl(), url, init);
|
||||||
|
addTask(promise);
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function baseUrl(url?: string): string {
|
||||||
|
if (url) {
|
||||||
|
if (domain.active) {
|
||||||
|
// There's an active domain (e.g., in Node.js), so associate the base URL with it
|
||||||
|
domainContext.set(domainTaskStateKey, url);
|
||||||
|
} else {
|
||||||
|
// There's no active domain (e.g., in browser), so there's just one shared base URL
|
||||||
|
noDomainBaseUrl = url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return domain.active ? domainContext.get(domainTaskStateKey) : noDomainBaseUrl;
|
||||||
|
}
|
||||||
4
src/Microsoft.AspNet.SpaServices/npm/domain-task/src/isomorphic-fetch.d.ts
vendored
Normal file
4
src/Microsoft.AspNet.SpaServices/npm/domain-task/src/isomorphic-fetch.d.ts
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
declare module 'isomorphic-fetch' {
|
||||||
|
var fetch: (url: string | Request, init?: RequestInit) => Promise<any>;
|
||||||
|
export default fetch;
|
||||||
|
}
|
||||||
59
src/Microsoft.AspNet.SpaServices/npm/domain-task/src/main.ts
Normal file
59
src/Microsoft.AspNet.SpaServices/npm/domain-task/src/main.ts
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import * as domain from 'domain';
|
||||||
|
import * as domainContext from 'domain-context';
|
||||||
|
const domainTasksStateKey = '__DOMAIN_TASKS';
|
||||||
|
|
||||||
|
export function addTask(task: PromiseLike<any>) {
|
||||||
|
if (task && domain.active) {
|
||||||
|
const state = domainContext.get(domainTasksStateKey) as DomainTasksState;
|
||||||
|
if (state) {
|
||||||
|
state.numRemainingTasks++;
|
||||||
|
task.then(() => {
|
||||||
|
// The application may have other listeners chained to this promise *after*
|
||||||
|
// this listener. Since we don't want the combined task to complete until
|
||||||
|
// all the handlers for child tasks have finished, delay the following by
|
||||||
|
// one tick.
|
||||||
|
setTimeout(() => {
|
||||||
|
state.numRemainingTasks--;
|
||||||
|
if (state.numRemainingTasks === 0 && !state.hasIssuedSuccessCallback) {
|
||||||
|
state.hasIssuedSuccessCallback = true;
|
||||||
|
state.completionCallback(/* error */ null);
|
||||||
|
}
|
||||||
|
}, 0);
|
||||||
|
}, (error) => {
|
||||||
|
state.completionCallback(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function run<T>(codeToRun: () => T, completionCallback: (error: any) => void): T {
|
||||||
|
let synchronousResult: T;
|
||||||
|
domainContext.runInNewDomain(() => {
|
||||||
|
const state: DomainTasksState = {
|
||||||
|
numRemainingTasks: 0,
|
||||||
|
hasIssuedSuccessCallback: false,
|
||||||
|
completionCallback: domain.active.bind(completionCallback)
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
domainContext.set(domainTasksStateKey, state);
|
||||||
|
synchronousResult = codeToRun();
|
||||||
|
|
||||||
|
// If no tasks were registered synchronously, then we're done already
|
||||||
|
if (state.numRemainingTasks === 0 && !state.hasIssuedSuccessCallback) {
|
||||||
|
state.hasIssuedSuccessCallback = true;
|
||||||
|
state.completionCallback(/* error */ null);
|
||||||
|
}
|
||||||
|
} catch(ex) {
|
||||||
|
state.completionCallback(ex);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return synchronousResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface DomainTasksState {
|
||||||
|
numRemainingTasks: number;
|
||||||
|
hasIssuedSuccessCallback: boolean;
|
||||||
|
completionCallback: (error: any) => void;
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"module": "commonjs",
|
||||||
|
"target": "es5",
|
||||||
|
"declaration": true,
|
||||||
|
"outDir": "."
|
||||||
|
},
|
||||||
|
"exclude": [
|
||||||
|
"node_modules"
|
||||||
|
]
|
||||||
|
}
|
||||||
18
src/Microsoft.AspNet.SpaServices/npm/domain-task/tsd.json
Normal file
18
src/Microsoft.AspNet.SpaServices/npm/domain-task/tsd.json
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"version": "v4",
|
||||||
|
"repo": "borisyankov/DefinitelyTyped",
|
||||||
|
"ref": "master",
|
||||||
|
"path": "typings",
|
||||||
|
"bundle": "typings/tsd.d.ts",
|
||||||
|
"installed": {
|
||||||
|
"node/node.d.ts": {
|
||||||
|
"commit": "3030a4be536b6530c06b80081f1333dc0de4d703"
|
||||||
|
},
|
||||||
|
"es6-promise/es6-promise.d.ts": {
|
||||||
|
"commit": "3030a4be536b6530c06b80081f1333dc0de4d703"
|
||||||
|
},
|
||||||
|
"whatwg-fetch/whatwg-fetch.d.ts": {
|
||||||
|
"commit": "3030a4be536b6530c06b80081f1333dc0de4d703"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user