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": {
|
||||
"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-redux/react-router-redux.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