diff --git a/API.md b/API.md
index c8c7e995..734bdb79 100644
--- a/API.md
+++ b/API.md
@@ -344,6 +344,21 @@ findChild(id: string): IConstruct
__Returns__:
* [IConstruct](#constructs-iconstruct)
+#### getAllContext(defaults?)
+
+Retrieves the all context of a node from tree context.
+
+Context is usually initialized at the root, but can be overridden at any point in the tree.
+
+```ts
+getAllContext(defaults?: json): any
+```
+
+* **defaults** (json
) Any keys to override the retrieved context.
+
+__Returns__:
+* any
+
#### getContext(key)
Retrieves a value from tree context if present. Otherwise, would throw an error.
diff --git a/src/construct.ts b/src/construct.ts
index 1888384b..1dc25ce8 100644
--- a/src/construct.ts
+++ b/src/construct.ts
@@ -44,7 +44,7 @@ export class Node {
/**
* The id of this construct within the current scope.
*
- * This is a a scope-unique id. To obtain an app-unique id for this construct, use `addr`.
+ * This is a scope-unique id. To obtain an app-unique id for this construct, use `addr`.
*/
public readonly id: string;
@@ -236,6 +236,25 @@ export class Node {
return this.scope && this.scope.node.getContext(key);
}
+ /**
+ * Retrieves the all context of a node from tree context.
+ *
+ * Context is usually initialized at the root, but can be overridden at any point in the tree.
+ *
+ * @param defaults Any keys to override the retrieved context
+ * @returns The context object or an empty object if there is discovered context
+ */
+ public getAllContext(defaults?: object): any {
+ if (typeof defaults === 'undefined') {
+ defaults = {};
+ }
+
+ if (this.scope === undefined) { return defaults; }
+
+ const value = { ...this._context, ...defaults };
+ return this.scope && this.scope.node.getAllContext(value);
+ }
+
/**
* Retrieves a value from tree context.
*
diff --git a/test/construct.test.ts b/test/construct.test.ts
index d46f0a79..ecfee0da 100644
--- a/test/construct.test.ts
+++ b/test/construct.test.ts
@@ -150,6 +150,22 @@ test('construct.getContext(key) throws if context is not defined', () => {
}).toThrowError(`No context value present for ${key} key`);
});
+test('construct.getAllContext can be used to read the full context of a node', () => {
+ // GIVEN
+ const context = {
+ ctx1: 12,
+ ctx2: 'hello',
+ };
+
+ // WHEN
+ const t = createTree(context);
+ t.child1_1_1.node.setContext('ctx1', 13);
+
+ // THEN
+ expect(t.child1_2.node.getAllContext()).toStrictEqual(context);
+ expect(t.child1_1_1.node.getAllContext()).toStrictEqual({ ctx1: 13, ctx2: 'hello' });
+});
+
test('construct.tryGetContext(key) can be used to read a value from context defined at the root level', () => {
const context = {
ctx1: 12,