| @@ -0,0 +1,25 | |||||
|
|
1 | @startuml | |||
|
|
2 | ||||
|
|
3 | participant Component as a | |||
|
|
4 | participant Other as b | |||
|
|
5 | ||||
|
|
6 | [-> a : activate(ct) | |||
|
|
7 | activate a | |||
|
|
8 | <-- a : promise | |||
|
|
9 | a -> a : onActivating(ct) | |||
|
|
10 | activate a | |||
|
|
11 | a -> b : doAsyncWork(ct) | |||
|
|
12 | deactivate a | |||
|
|
13 | deactivate a | |||
|
|
14 | activate b | |||
|
|
15 | ||||
|
|
16 | [-> b : ct.cancel | |||
|
|
17 | b --> a : reject(Cancelled) | |||
|
|
18 | deactivate b | |||
|
|
19 | activate a | |||
|
|
20 | ||||
|
|
21 | a -> a : setFailState() | |||
|
|
22 | ||||
|
|
23 | [<-- a : reject(Cancelled) | |||
|
|
24 | ||||
|
|
25 | @enduml No newline at end of file | |||
| @@ -0,0 +1,20 | |||||
|
|
1 | import { ICancellation } from "./ICancellation"; | |||
|
|
2 | ||||
|
|
3 | export class EmptyCancellation implements ICancellation { | |||
|
|
4 | isSupported(): boolean { | |||
|
|
5 | return false; | |||
|
|
6 | } | |||
|
|
7 | throwIfRequested(): void { | |||
|
|
8 | } | |||
|
|
9 | ||||
|
|
10 | isRequested(): boolean { | |||
|
|
11 | return false; | |||
|
|
12 | } | |||
|
|
13 | ||||
|
|
14 | register(_cb: () => void): void { | |||
|
|
15 | ||||
|
|
16 | } | |||
|
|
17 | ||||
|
|
18 | static readonly default : EmptyCancellation = new EmptyCancellation(); | |||
|
|
19 | ||||
|
|
20 | } No newline at end of file | |||
| @@ -0,0 +1,6 | |||||
|
|
1 | export interface ICancellation { | |||
|
|
2 | throwIfRequested(): void; | |||
|
|
3 | isRequested(): boolean; | |||
|
|
4 | isSupported(): boolean; | |||
|
|
5 | register(cb: () => void): void; | |||
|
|
6 | } No newline at end of file | |||
| @@ -0,0 +1,92 | |||||
|
|
1 | import { IActivationController } from './IActivationController'; | |||
|
|
2 | import { IActivatable } from './IActivatable'; | |||
|
|
3 | import { AsyncComponent } from './AsyncComponent'; | |||
|
|
4 | import { ICancellation } from '../ICancellation'; | |||
|
|
5 | import { EmptyCancellation } from '../EmptyCancellation'; | |||
|
|
6 | ||||
|
|
7 | type Constructor<T = {}> = new (...args: any[]) => T; | |||
|
|
8 | ||||
|
|
9 | function ActivatableMixin<TBase extends Constructor<AsyncComponent>>(Base: TBase) { | |||
|
|
10 | return class extends Base implements IActivatable { | |||
|
|
11 | _controller: IActivationController; | |||
|
|
12 | ||||
|
|
13 | _active: boolean; | |||
|
|
14 | ||||
|
|
15 | isActive() { | |||
|
|
16 | return this._active; | |||
|
|
17 | } | |||
|
|
18 | ||||
|
|
19 | getActivationController() { | |||
|
|
20 | return this._controller; | |||
|
|
21 | } | |||
|
|
22 | ||||
|
|
23 | setActivationController(controller: IActivationController) { | |||
|
|
24 | this._controller = controller; | |||
|
|
25 | } | |||
|
|
26 | ||||
|
|
27 | async onActivating(ct: ICancellation) { | |||
|
|
28 | if (this._controller) | |||
|
|
29 | await this._controller.activating(this, ct); | |||
|
|
30 | } | |||
|
|
31 | ||||
|
|
32 | async onActivated(ct: ICancellation) { | |||
|
|
33 | if (this._controller) | |||
|
|
34 | await this._controller.activated(this, ct); | |||
|
|
35 | } | |||
|
|
36 | ||||
|
|
37 | async activate(ct: ICancellation = EmptyCancellation.default) { | |||
|
|
38 | if (this.isActive()) | |||
|
|
39 | return; | |||
|
|
40 | ct = this.startOperation(ct); | |||
|
|
41 | try { | |||
|
|
42 | await this.onActivating(ct); | |||
|
|
43 | this._active = true; | |||
|
|
44 | try { | |||
|
|
45 | await this.onActivated(ct); | |||
|
|
46 | } catch { | |||
|
|
47 | // TODO log error | |||
|
|
48 | } | |||
|
|
49 | this.completeSuccess(); | |||
|
|
50 | } catch (e) { | |||
|
|
51 | this.completeFail(e); | |||
|
|
52 | } | |||
|
|
53 | return this.getCompletion(); | |||
|
|
54 | } | |||
|
|
55 | ||||
|
|
56 | async onDeactivating(ct: ICancellation) { | |||
|
|
57 | if (this._controller) | |||
|
|
58 | await this._controller.deactivating(this, ct); | |||
|
|
59 | } | |||
|
|
60 | ||||
|
|
61 | async onDeactivated(ct: ICancellation) { | |||
|
|
62 | if (this._controller) | |||
|
|
63 | await this._controller.deactivated(this, ct); | |||
|
|
64 | } | |||
|
|
65 | ||||
|
|
66 | async deactivate(ct: ICancellation = EmptyCancellation.default) { | |||
|
|
67 | if (!this.isActive()) | |||
|
|
68 | return; | |||
|
|
69 | ct = this.startOperation(ct); | |||
|
|
70 | try { | |||
|
|
71 | await this.onDeactivating(ct); | |||
|
|
72 | this._active = false; | |||
|
|
73 | try { | |||
|
|
74 | await this.onDeactivated(ct); | |||
|
|
75 | } catch { | |||
|
|
76 | // TODO log error | |||
|
|
77 | } | |||
|
|
78 | this.completeSuccess(); | |||
|
|
79 | } catch (e) { | |||
|
|
80 | this.completeFail(e); | |||
|
|
81 | } | |||
|
|
82 | return this.getCompletion(); | |||
|
|
83 | } | |||
|
|
84 | ||||
|
|
85 | } | |||
|
|
86 | } | |||
|
|
87 | ||||
|
|
88 | namespace ActivatableMixin { | |||
|
|
89 | ||||
|
|
90 | } | |||
|
|
91 | ||||
|
|
92 | export = ActivatableMixin; No newline at end of file | |||
| @@ -0,0 +1,47 | |||||
|
|
1 | import { ICancellation } from "../ICancellation"; | |||
|
|
2 | import { EmptyCancellation } from "../EmptyCancellation"; | |||
|
|
3 | ||||
|
|
4 | export class AsyncComponent { | |||
|
|
5 | _completion: Promise<void>; | |||
|
|
6 | ||||
|
|
7 | _deferred: { | |||
|
|
8 | resolve(): void | |||
|
|
9 | reject(reason: any): void | |||
|
|
10 | }; | |||
|
|
11 | ||||
|
|
12 | getCompletion() { return this._completion }; | |||
|
|
13 | ||||
|
|
14 | startOperation(ct: ICancellation = EmptyCancellation.default) { | |||
|
|
15 | if (this._deferred) | |||
|
|
16 | throw new Error("The async operation is already pending"); | |||
|
|
17 | ||||
|
|
18 | this._completion = new Promise<void>((resolve, reject) => { | |||
|
|
19 | this._deferred = { | |||
|
|
20 | resolve: resolve, | |||
|
|
21 | reject: reject | |||
|
|
22 | } | |||
|
|
23 | }); | |||
|
|
24 | return ct; | |||
|
|
25 | } | |||
|
|
26 | ||||
|
|
27 | completeSuccess() { | |||
|
|
28 | this._deferred.resolve(); | |||
|
|
29 | this._deferred = null; | |||
|
|
30 | } | |||
|
|
31 | ||||
|
|
32 | completeFail(reason: any) { | |||
|
|
33 | this._deferred.reject(reason); | |||
|
|
34 | this._deferred = null; | |||
|
|
35 | } | |||
|
|
36 | ||||
|
|
37 | async runOperation(cb: (ct: ICancellation) => Promise<void>, ct: ICancellation = EmptyCancellation.default) { | |||
|
|
38 | //safe.argumentNotNull(cb, "cb") | |||
|
|
39 | ct = this.startOperation(ct); | |||
|
|
40 | try { | |||
|
|
41 | await cb(ct); | |||
|
|
42 | this.completeSuccess(); | |||
|
|
43 | } catch(e) { | |||
|
|
44 | this.completeFail(e); | |||
|
|
45 | } | |||
|
|
46 | } | |||
|
|
47 | } No newline at end of file | |||
| @@ -0,0 +1,39 | |||||
|
|
1 | import { IActivationController } from "./IActivationController"; | |||
|
|
2 | import { ICancellation } from "../ICancellation"; | |||
|
|
3 | ||||
|
|
4 | /** | |||
|
|
5 | * Интерфейс поддерживающий асинхронную активацию | |||
|
|
6 | */ | |||
|
|
7 | export interface IActivatable { | |||
|
|
8 | /** | |||
|
|
9 | * @returns Boolean indicates the current state | |||
|
|
10 | */ | |||
|
|
11 | isActive(): boolean; | |||
|
|
12 | ||||
|
|
13 | /** | |||
|
|
14 | * Starts the component activation | |||
|
|
15 | * @param ct cancellation token for this operation | |||
|
|
16 | */ | |||
|
|
17 | activate(ct?: ICancellation): Promise<void>; | |||
|
|
18 | ||||
|
|
19 | /** | |||
|
|
20 | * Starts the component deactivation | |||
|
|
21 | * @param ct cancellation token for this operation | |||
|
|
22 | */ | |||
|
|
23 | deactivate(ct?: ICancellation): Promise<void>; | |||
|
|
24 | ||||
|
|
25 | /** | |||
|
|
26 | * Sets the activation controller for this component | |||
|
|
27 | * @param controller The activation controller | |||
|
|
28 | * | |||
|
|
29 | * Activation controller checks whether this component | |||
|
|
30 | * can be activated and manages the active state of the | |||
|
|
31 | * component | |||
|
|
32 | */ | |||
|
|
33 | setActivationController(controller: IActivationController); | |||
|
|
34 | ||||
|
|
35 | /** | |||
|
|
36 | * Gets the current activation controller for this component | |||
|
|
37 | */ | |||
|
|
38 | getActivationController(): IActivationController; | |||
|
|
39 | } No newline at end of file | |||
| @@ -0,0 +1,19 | |||||
|
|
1 | import { IActivatable } from './IActivatable'; | |||
|
|
2 | import { ICancellation } from '../ICancellation'; | |||
|
|
3 | import { EmptyCancellation } from '../EmptyCancellation'; | |||
|
|
4 | ||||
|
|
5 | export interface IActivationController { | |||
|
|
6 | activating(component: IActivatable, ct?: ICancellation): Promise<void>; | |||
|
|
7 | ||||
|
|
8 | activated(component: IActivatable, ct?: ICancellation): Promise<void>; | |||
|
|
9 | ||||
|
|
10 | deactivating(component: IActivatable, ct?: ICancellation): Promise<void>; | |||
|
|
11 | ||||
|
|
12 | deactivated(component: IActivatable, ct?: ICancellation): Promise<void>; | |||
|
|
13 | ||||
|
|
14 | deactivate(ct?: ICancellation): Promise<void>; | |||
|
|
15 | ||||
|
|
16 | activate(component: IActivatable, ct?: ICancellation): Promise<void>; | |||
|
|
17 | ||||
|
|
18 | getActive(): IActivatable; | |||
|
|
19 | } No newline at end of file | |||
| @@ -0,0 +1,20 | |||||
|
|
1 | import * as TraceSource from './TraceSource' | |||
|
|
2 | ||||
|
|
3 | class TraceEventArgs { | |||
|
|
4 | source : TraceSource | |||
|
|
5 | ||||
|
|
6 | message : string | |||
|
|
7 | ||||
|
|
8 | level : number | |||
|
|
9 | ||||
|
|
10 | constructor(source: TraceSource, message: string) { | |||
|
|
11 | this.source = source; | |||
|
|
12 | this.message = message; | |||
|
|
13 | } | |||
|
|
14 | } | |||
|
|
15 | ||||
|
|
16 | namespace TraceEventArgs { | |||
|
|
17 | ||||
|
|
18 | } | |||
|
|
19 | ||||
|
|
20 | export = TraceEventArgs No newline at end of file | |||
| @@ -0,0 +1,116 | |||||
|
|
1 | import * as TraceEventArgs from './TraceEventArgs' | |||
|
|
2 | import * as format from '../text/format' | |||
|
|
3 | ||||
|
|
4 | interface Handler { | |||
|
|
5 | (arg: TraceEventArgs): void; | |||
|
|
6 | } | |||
|
|
7 | ||||
|
|
8 | interface Destroyable { | |||
|
|
9 | destroy(); | |||
|
|
10 | } | |||
|
|
11 | ||||
|
|
12 | class HandlerDescriptor implements Destroyable { | |||
|
|
13 | private _target: TraceSource | |||
|
|
14 | ||||
|
|
15 | readonly handler: Handler; | |||
|
|
16 | ||||
|
|
17 | constructor(target: TraceSource, handler: Handler) { | |||
|
|
18 | this._target = target; | |||
|
|
19 | this.handler = handler; | |||
|
|
20 | } | |||
|
|
21 | ||||
|
|
22 | destroy() { | |||
|
|
23 | this._target.remove(this); | |||
|
|
24 | } | |||
|
|
25 | } | |||
|
|
26 | ||||
|
|
27 | ||||
|
|
28 | class TraceSource { | |||
|
|
29 | readonly id: any | |||
|
|
30 | ||||
|
|
31 | private _handlers: Array<HandlerDescriptor> | |||
|
|
32 | ||||
|
|
33 | level: number | |||
|
|
34 | ||||
|
|
35 | constructor(id: any) { | |||
|
|
36 | this.id = id || new Object(); | |||
|
|
37 | this._handlers = new Array<HandlerDescriptor>(); | |||
|
|
38 | } | |||
|
|
39 | ||||
|
|
40 | on(handler: Handler): Destroyable { | |||
|
|
41 | if (!handler) | |||
|
|
42 | throw new Error("A handler must be specified"); | |||
|
|
43 | ||||
|
|
44 | let d = new HandlerDescriptor(this, handler) | |||
|
|
45 | ||||
|
|
46 | this._handlers.push(d); | |||
|
|
47 | ||||
|
|
48 | return d; | |||
|
|
49 | } | |||
|
|
50 | ||||
|
|
51 | remove(cookie: any): void { | |||
|
|
52 | let i = this._handlers.indexOf(cookie); | |||
|
|
53 | if (i >= 0) | |||
|
|
54 | this._handlers.splice(i, 1); | |||
|
|
55 | } | |||
|
|
56 | ||||
|
|
57 | protected emit(level: number, msg: string, ...args: any[]) { | |||
|
|
58 | if (level <= this.level) { | |||
|
|
59 | let event = new TraceEventArgs(this, format(msg, args)); | |||
|
|
60 | ||||
|
|
61 | this._handlers.forEach(d => { | |||
|
|
62 | try { | |||
|
|
63 | d.handler.call(null, event); | |||
|
|
64 | } catch { | |||
|
|
65 | // suppress error in log handlers | |||
|
|
66 | } | |||
|
|
67 | }); | |||
|
|
68 | } | |||
|
|
69 | } | |||
|
|
70 | ||||
|
|
71 | isDebugEnabled() { | |||
|
|
72 | return this.level >= TraceSource.DebugLevel; | |||
|
|
73 | } | |||
|
|
74 | ||||
|
|
75 | debug(msg: string, ...args: any[]): void { | |||
|
|
76 | this.emit(TraceSource.DebugLevel, msg, args); | |||
|
|
77 | } | |||
|
|
78 | ||||
|
|
79 | isLogEnabled() { | |||
|
|
80 | return this.level >= TraceSource.LogLevel; | |||
|
|
81 | } | |||
|
|
82 | ||||
|
|
83 | log(msg: string, ...args: any[]): void { | |||
|
|
84 | this.emit(TraceSource.LogLevel, msg, args); | |||
|
|
85 | } | |||
|
|
86 | ||||
|
|
87 | isWarnEnabled() { | |||
|
|
88 | return this.level >= TraceSource.WarnLevel; | |||
|
|
89 | } | |||
|
|
90 | ||||
|
|
91 | warn(msg: string, ...args: any[]): void { | |||
|
|
92 | this.emit(TraceSource.WarnLevel, msg, args); | |||
|
|
93 | } | |||
|
|
94 | ||||
|
|
95 | isErrorEnabled() { | |||
|
|
96 | return this.level >= TraceSource.ErrorLevel; | |||
|
|
97 | } | |||
|
|
98 | ||||
|
|
99 | error(msg: string, ...args: any[]): void { | |||
|
|
100 | this.emit(TraceSource.ErrorLevel, msg, args); | |||
|
|
101 | } | |||
|
|
102 | } | |||
|
|
103 | ||||
|
|
104 | namespace TraceSource { | |||
|
|
105 | export const DebugLevel = 400; | |||
|
|
106 | ||||
|
|
107 | export const LogLevel = 300; | |||
|
|
108 | ||||
|
|
109 | export const WarnLevel = 200; | |||
|
|
110 | ||||
|
|
111 | export const ErrorLevel = 100; | |||
|
|
112 | ||||
|
|
113 | export const SilentLevel = 0; | |||
|
|
114 | } | |||
|
|
115 | ||||
|
|
116 | export = TraceSource; No newline at end of file | |||
| @@ -0,0 +1,7 | |||||
|
|
1 | declare function format(format: string, ...args: any[]): string; | |||
|
|
2 | ||||
|
|
3 | declare namespace format { | |||
|
|
4 | ||||
|
|
5 | } | |||
|
|
6 | ||||
|
|
7 | export = format; No newline at end of file | |||
| @@ -0,0 +1,110 | |||||
|
|
1 | import * as tape from 'tape'; | |||
|
|
2 | import * as ActivatableMixin from '@implab/core/components/ActivatableMixin'; | |||
|
|
3 | import { AsyncComponent } from '@implab/core/components/AsyncComponent'; | |||
|
|
4 | import { IActivationController } from '@implab/core/components/IActivationController'; | |||
|
|
5 | import { IActivatable } from '@implab/core/components/IActivatable'; | |||
|
|
6 | import { ICancellation } from '@implab/core/ICancellation'; | |||
|
|
7 | import { EmptyCancellation } from '@implab/core/EmptyCancellation'; | |||
|
|
8 | ||||
|
|
9 | class SimpleActivatable extends ActivatableMixin(AsyncComponent) { | |||
|
|
10 | ||||
|
|
11 | } | |||
|
|
12 | ||||
|
|
13 | class MockActivationController implements IActivationController { | |||
|
|
14 | ||||
|
|
15 | _active: IActivatable = null; | |||
|
|
16 | ||||
|
|
17 | ||||
|
|
18 | getActive() : IActivatable { | |||
|
|
19 | return this._active; | |||
|
|
20 | } | |||
|
|
21 | ||||
|
|
22 | async deactivate() { | |||
|
|
23 | if (this._active) | |||
|
|
24 | await this._active.deactivate(); | |||
|
|
25 | this._active = null; | |||
|
|
26 | } | |||
|
|
27 | ||||
|
|
28 | async activate(component: IActivatable) { | |||
|
|
29 | if (!component || component.isActive()) | |||
|
|
30 | return; | |||
|
|
31 | component.setActivationController(this); | |||
|
|
32 | ||||
|
|
33 | await component.activate(); | |||
|
|
34 | } | |||
|
|
35 | ||||
|
|
36 | async activating(component: IActivatable, ct: ICancellation = EmptyCancellation.default) { | |||
|
|
37 | if (component != this._active) | |||
|
|
38 | await this.deactivate(); | |||
|
|
39 | } | |||
|
|
40 | ||||
|
|
41 | async activated(component: IActivatable, ct: ICancellation = EmptyCancellation.default) { | |||
|
|
42 | this._active = component; | |||
|
|
43 | } | |||
|
|
44 | ||||
|
|
45 | async deactivating(component: IActivatable, ct: ICancellation = EmptyCancellation.default) { | |||
|
|
46 | ||||
|
|
47 | } | |||
|
|
48 | ||||
|
|
49 | async deactivated(component: IActivatable, ct: ICancellation = EmptyCancellation.default) { | |||
|
|
50 | if (this._active == component) | |||
|
|
51 | this._active = null; | |||
|
|
52 | } | |||
|
|
53 | } | |||
|
|
54 | ||||
|
|
55 | tape('simple activation',async function(t){ | |||
|
|
56 | ||||
|
|
57 | let a = new SimpleActivatable(); | |||
|
|
58 | t.false(a.isActive()); | |||
|
|
59 | ||||
|
|
60 | await a.activate(); | |||
|
|
61 | t.true(a.isActive()); | |||
|
|
62 | ||||
|
|
63 | await a.deactivate(); | |||
|
|
64 | t.false(a.isActive()); | |||
|
|
65 | ||||
|
|
66 | t.end(); | |||
|
|
67 | }); | |||
|
|
68 | ||||
|
|
69 | tape('controller activation', async function(t) { | |||
|
|
70 | ||||
|
|
71 | let a = new SimpleActivatable(); | |||
|
|
72 | let c = new MockActivationController(); | |||
|
|
73 | ||||
|
|
74 | t.false(a.isActive(), "the component is not active by default"); | |||
|
|
75 | t.assert(c.getActive() == null, "the activation controller doesn't have an active component by default"); | |||
|
|
76 | t.assert(a.getActivationController() == null, "the component doesn't have an activation controller by default"); | |||
|
|
77 | ||||
|
|
78 | t.comment("Active the component through the controller"); | |||
|
|
79 | await c.activate(a); | |||
|
|
80 | t.true(a.isActive(), "The component should successfully activate"); | |||
|
|
81 | t.assert(c.getActive() == a, "The controller should point to the activated component"); | |||
|
|
82 | t.assert(a.getActivationController() == c, "The component should point to the controller"); | |||
|
|
83 | ||||
|
|
84 | t.comment("Deactive the component throug the controller"); | |||
|
|
85 | await c.deactivate(); | |||
|
|
86 | ||||
|
|
87 | t.false(a.isActive(), "The component should successfully deactivate"); | |||
|
|
88 | t.assert(c.getActive() == null, "The controller shouldn't point to any component"); | |||
|
|
89 | t.assert(a.getActivationController() == c, "The componet should point to it's controller"); | |||
|
|
90 | ||||
|
|
91 | t.end(); | |||
|
|
92 | }); | |||
|
|
93 | ||||
|
|
94 | tape('handle error in onActivating', async function(t) { | |||
|
|
95 | let a = new SimpleActivatable(); | |||
|
|
96 | ||||
|
|
97 | a.onActivating = async function() { | |||
|
|
98 | throw "Should fail"; | |||
|
|
99 | }; | |||
|
|
100 | ||||
|
|
101 | try { | |||
|
|
102 | await a.activate(); | |||
|
|
103 | t.fail("activation should fail"); | |||
|
|
104 | } catch { | |||
|
|
105 | } | |||
|
|
106 | ||||
|
|
107 | t.false(a.isActive(), "the component should remain inactive"); | |||
|
|
108 | ||||
|
|
109 | t.end(); | |||
|
|
110 | }); No newline at end of file | |||
| @@ -7,6 +7,7 def testDir = "$buildDir/test" | |||||
| 7 | task clean { |
|
7 | task clean { | |
| 8 | doLast { |
|
8 | doLast { | |
| 9 | delete buildDir |
|
9 | delete buildDir | |
|
|
10 | delete 'node_modules/@implab' | |||
| 10 | } |
|
11 | } | |
| 11 | } |
|
12 | } | |
| 12 |
|
13 | |||
| @@ -110,7 +110,7 define([ | |||||
| 110 | if (typeof (config) === "string") { |
|
110 | if (typeof (config) === "string") { | |
| 111 | p = new Deferred(); |
|
111 | p = new Deferred(); | |
| 112 | if (!contextRequire) { |
|
112 | if (!contextRequire) { | |
| 113 |
var shim = [config, |
|
113 | var shim = [config, Uuid()].join(config.indexOf("/") != -1 ? "-" : "/"); | |
| 114 | define(shim, ["require", config], function (ctx, data) { |
|
114 | define(shim, ["require", config], function (ctx, data) { | |
| 115 | p.resolve([data, { |
|
115 | p.resolve([data, { | |
| 116 | contextRequire: ctx |
|
116 | contextRequire: ctx | |
| @@ -175,11 +175,13 define([], | |||||
| 175 | } |
|
175 | } | |
| 176 | } |
|
176 | } | |
| 177 |
|
177 | |||
| 178 |
|
|
178 | return function() { | |
| 179 | return wrapresult(fn.apply(thisArg, arguments)); |
|
179 | try { | |
| 180 | } catch (e) { |
|
180 | return wrapresult(fn.apply(thisArg, arguments)); | |
| 181 |
|
|
181 | } catch (e) { | |
| 182 | } |
|
182 | return wrapresult(null, e); | |
|
|
183 | } | |||
|
|
184 | }; | |||
| 183 | }, |
|
185 | }, | |
| 184 |
|
186 | |||
| 185 | create: function () { |
|
187 | create: function () { | |
| @@ -6,6 +6,8 | |||||
| 6 | // Copyright (c) 2010-2012 Robert Kieffer |
|
6 | // Copyright (c) 2010-2012 Robert Kieffer | |
| 7 | // MIT License - http://opensource.org/licenses/mit-license.php |
|
7 | // MIT License - http://opensource.org/licenses/mit-license.php | |
| 8 |
|
8 | |||
|
|
9 | declare var window: any; | |||
|
|
10 | ||||
| 9 | let _window : any = 'undefined' !== typeof window ? window : null; |
|
11 | let _window : any = 'undefined' !== typeof window ? window : null; | |
| 10 |
|
12 | |||
| 11 | // Unique ID creation requires a high quality random # generator. We |
|
13 | // Unique ID creation requires a high quality random # generator. We | |
| @@ -1,1 +1,1 | |||||
| 1 | define(["./dummy", "./example"]); No newline at end of file |
|
1 | define(["./dummy", "./example", "./ActivatableTests"]); No newline at end of file | |
| @@ -4,7 +4,10 | |||||
| 4 | "module": "amd", |
|
4 | "module": "amd", | |
| 5 | "sourceMap": true, |
|
5 | "sourceMap": true, | |
| 6 | "outDir" : "build/dist", |
|
6 | "outDir" : "build/dist", | |
| 7 | "declaration": true |
|
7 | "declaration": true, | |
|
|
8 | "lib": [ | |||
|
|
9 | "ES2015" | |||
|
|
10 | ] | |||
| 8 | }, |
|
11 | }, | |
| 9 | "include" : [ |
|
12 | "include" : [ | |
| 10 | "src/ts/**/*.ts" |
|
13 | "src/ts/**/*.ts" | |
| @@ -4,7 +4,10 | |||||
| 4 | "module": "amd", |
|
4 | "module": "amd", | |
| 5 | "sourceMap": true, |
|
5 | "sourceMap": true, | |
| 6 | "outDir" : "build/test", |
|
6 | "outDir" : "build/test", | |
| 7 | "moduleResolution": "node" |
|
7 | "moduleResolution": "node", | |
|
|
8 | "lib": [ | |||
|
|
9 | "ES2015" | |||
|
|
10 | ] | |||
| 8 | }, |
|
11 | }, | |
| 9 | "include" : [ |
|
12 | "include" : [ | |
| 10 | "test/ts/**/*.ts" |
|
13 | "test/ts/**/*.ts" | |
| 1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
| 1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
General Comments 0
You need to be logged in to leave comments.
Login now
