npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

proxy-views

v0.0.2

Published

Some wrapper views for Plain Data Object with ES6 Proxy. Make Data Object more semantic and easier to use.

Downloads

11

Readme

proxy-views.js


🇨🇳 中文文档 {#中文文档}

✨ 核心特性

  • 🔒 StrictView: 严格模式,只允许访问已定义的属性
  • 🔗 AliasView: 为复杂嵌套属性创建简洁别名
  • ⛓️ ChainView: 将多个字典链接成单一只读视图
  • 🛡️ MissingView: 基础包装,自定义缺失属性处理
  • 📦 零依赖: 纯 JavaScript 实现,无外部依赖
  • 🎯 非侵入: 不修改原始对象,只提供包装视图

📦 安装

npm install proxy-views

🚀 快速开始

1. ChainView - 链式字典视图

将多个字典链接成一个只读视图,支持链式查找和唯一遍历。

const { ChainView } = require('proxy-views');

const defaults = { theme: 'light', lang: 'en', debug: false };
const userPrefs = { theme: 'dark', lang: 'zh' };
const session = { debug: true, user: 'alice' };

const config = new ChainView(userPrefs, defaults, session);

// 链式查找:从第一个字典开始找,找不到继续向后找
console.log(config.theme); // 'dark' (来自 userPrefs)
console.log(config.debug); // true (来自 session)
console.log(config.port); // undefined (不存在)

// 只读访问:不能修改
config.newProp = 'value'; // Error: Cannot set property 'newProp' on ChainView (read-only)

// 遍历所有唯一键
for (const key of config) {
  console.log(key, config[key]);
}
// 输出: theme dark, lang zh, debug true, user alice

// 获取所有键
console.log(Object.keys(config)); // ['theme', 'lang', 'debug', 'user']
console.log(config.length); // 4

2. StrictView - 严格模式

防止拼写错误或访问不存在的属性,让你的代码更安全。

const { StrictView } = require('proxy-views');

const user = {
  name: '张三',
  age: 25,
  address: { city: '北京', street: '中关村大街' }
};

const safeUser = new StrictView(user);

// ✅ 正常访问
console.log(safeUser.name); // '张三'
console.log(safeUser.address.city); // '北京'

// ❌ 错误访问会抛出明确的错误
console.log(safeUser.nmae); // Error: Property "nmae" is not defined

2. AliasView - 属性别名

为深层嵌套属性创建简洁的别名,告别冗长的属性链。

const { AliasView } = require('proxy-views');

const config = {
  server: {
    database: {
      host: 'localhost',
      port: 5432,
      credentials: { username: 'admin', password: 'secret' }
    }
  }
};

const view = new AliasView(config);

// 创建别名
view.alias('server.database.host', 'dbHost');
view.alias('server.database.port', 'dbPort');

// 🎉 简洁访问
console.log(view.dbHost); // 'localhost'
console.log(view.dbPort); // 5432

// 修改会同步更新原始对象
view.dbHost = 'prod.example.com';
console.log(config.server.database.host); // 'prod.example.com'

批量创建别名

const view = new AliasView(data);

// 多种方式
view.alias('user.name', ['displayName', 'nickname']);
view.alias('user.email', 'email', 'mail', 'userEmail');
view.alias('settings.theme', ['theme', 'colorScheme'], 'uiTheme');

数据导出

const view = new AliasView({ name: '王五', age: 30 });
view.alias('name', 'username');

// 完整导出
console.log(view.toJSON());
// { name: '王五', age: 30, username: '王五' }

// 只导出别名
console.log(view.toJSON({ target: false, alias: true }));
// { username: '王五' }

🎯 实际应用场景

1. 配置管理

const config = new AliasView(appConfig);
config.alias('database.connection.host', 'dbHost');
const connStr = `${config.dbHost}:${config.dbPort}`;

2. API 响应简化

const user = new AliasView(apiResponse);
user.alias('user.profile.display_name', 'name');
setUserInfo({ name: user.name });

3. 表单数据映射

const form = new AliasView(apiData);
form.alias('customer.billing_address.street', 'billingStreet');

📋 API 参考

StrictView

  • new StrictView(object) - 创建严格视图
  • 只能访问原始对象中存在的属性

AliasView

  • new AliasView(object) - 创建别名视图
  • view.alias(originPath, ...aliasNames) - 创建别名
  • view.toJSON(options) - 导出数据

ChainView

  • new ChainView(dict1, dict2, ...) - 创建链式字典视图
  • 只读访问,支持链式查找
  • 支持 Object.keys(), for...of, Object.entries() 等遍历方法

🇺🇸 English Documentation {#english-documentation}

✨ Core Features

  • 🔒 StrictView: Strict mode, only allow access to defined properties
  • 🔗 AliasView: Create simple aliases for complex nested properties
  • ⛓️ ChainView: Chain multiple dictionaries into a single read-only view
  • 🛡️ MissingView: Basic wrapper with custom missing property handling
  • 📦 Zero Dependencies: Pure JavaScript implementation, no external deps
  • 🎯 Non-invasive: Doesn't modify original object, only provides wrapper view

📦 Installation

npm install proxy-views

🚀 Quick Start

1. ChainView - Chain Dictionary View

Chain multiple dictionaries into a single read-only view with chain lookup and unique iteration.

const { ChainView } = require('proxy-views');

const defaults = { theme: 'light', lang: 'en', debug: false };
const userPrefs = { theme: 'dark', lang: 'zh' };
const session = { debug: true, user: 'alice' };

const config = new ChainView(userPrefs, defaults, session);

// Chain lookup: search from first dict, continue to next if not found
console.log(config.theme); // 'dark' (from userPrefs)
console.log(config.debug); // true (from session)
console.log(config.port); // undefined (not found)

// Read-only: cannot modify
config.newProp = 'value'; // Error: Cannot set property 'newProp' on ChainView (read-only)

// Iterate all unique keys
for (const key of config) {
  console.log(key, config[key]);
}
// Output: theme dark, lang zh, debug true, user alice

// Get all keys
console.log(Object.keys(config)); // ['theme', 'lang', 'debug', 'user']
console.log(config.length); // 4

2. StrictView - Strict Mode

Prevent typos or accessing non-existent properties, making your code safer.

const { StrictView } = require('proxy-views');

const user = {
  name: 'John',
  age: 25,
  address: { city: 'Beijing', street: 'Zhongguancun Street' }
};

const safeUser = new StrictView(user);

// ✅ Normal access
console.log(safeUser.name); // 'John'
console.log(safeUser.address.city); // 'Beijing'

// ❌ Error access throws clear error
console.log(safeUser.nmae); // Error: Property "nmae" is not defined

2. AliasView - Property Aliases

Create simple aliases for deeply nested properties, eliminating long property chains.

const { AliasView } = require('proxy-views');

const config = {
  server: {
    database: {
      host: 'localhost',
      port: 5432,
      credentials: { username: 'admin', password: 'secret' }
    }
  }
};

const view = new AliasView(config);

// Create aliases
view.alias('server.database.host', 'dbHost');
view.alias('server.database.port', 'dbPort');

// 🎉 Simple access
console.log(view.dbHost); // 'localhost'
console.log(view.dbPort); // 5432

// Changes sync to original object
view.dbHost = 'prod.example.com';
console.log(config.server.database.host); // 'prod.example.com'

Batch Alias Creation

const view = new AliasView(data);

// Multiple ways
view.alias('user.name', ['displayName', 'nickname']);
view.alias('user.email', 'email', 'mail', 'userEmail');
view.alias('settings.theme', ['theme', 'colorScheme'], 'uiTheme');

Data Export

const view = new AliasView({ name: 'John', age: 30 });
view.alias('name', 'username');

// Full export
console.log(view.toJSON());
// { name: 'John', age: 30, username: 'John' }

// Only aliases
console.log(view.toJSON({ target: false, alias: true }));
// { username: 'John' }

🎯 Real-world Use Cases

1. Configuration Management

const config = new AliasView(appConfig);
config.alias('database.connection.host', 'dbHost');
const connStr = `${config.dbHost}:${config.dbPort}`;

2. API Response Simplification

const user = new AliasView(apiResponse);
user.alias('user.profile.display_name', 'name');
setUserInfo({ name: user.name });

3. Form Data Mapping

const form = new AliasView(apiData);
form.alias('customer.billing_address.street', 'billingStreet');

📋 API Reference

StrictView

  • new StrictView(object) - Create strict view
  • Only access properties that exist in original object

AliasView

  • new AliasView(object) - Create alias view
  • view.alias(originPath, ...aliasNames) - Create aliases
  • view.toJSON(options) - Export data

ChainView

  • new ChainView(dict1, dict2, ...) - Create chain dictionary view
  • Read-only access with chain lookup
  • Supports Object.keys(), for...of, Object.entries() traversal methods

🤝 Contributing

欢迎提交 Issue 和 Pull Request! / Contributions are welcome!

📄 License

MIT License - see LICENSE file

📊 Changelog

0.0.2

  • Added ChainView: Chain dictionary view for read-only linking of multiple dictionaries
  • Supports chain lookup and unique key iteration
  • Fully compatible with standard iteration methods (Object.keys, for...of, Object.entries, etc.)

0.0.1

  • Initial release with MissingView, StrictView and AliasView base implementations